mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Move Headerer to different repo
This commit is contained in:
2
.github/workflows/build_and_publish.yml
vendored
2
.github/workflows/build_and_publish.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
project: [Headerer, RombaSharp, SabreTools]
|
project: [RombaSharp, SabreTools]
|
||||||
runtime: [win-x86, win-x64, win-arm64, linux-x64, linux-arm64, osx-x64]
|
runtime: [win-x86, win-x64, win-arm64, linux-x64, linux-arm64, osx-x64]
|
||||||
framework: [net8.0] #[net20, net35, net40, net452, net472, net48, netcoreapp3.1, net5.0, net6.0, net7.0, net8.0]
|
framework: [net8.0] #[net20, net35, net40, net452, net472, net48, netcoreapp3.1, net5.0, net6.0, net7.0, net8.0]
|
||||||
|
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using SabreTools.IO;
|
|
||||||
|
|
||||||
namespace Headerer
|
|
||||||
{
|
|
||||||
internal static class Database
|
|
||||||
{
|
|
||||||
#region Constants
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default location for the database
|
|
||||||
/// </summary>
|
|
||||||
private static readonly string DbFileName = Path.Combine(PathTool.GetRuntimeDirectory(), "Headerer.sqlite");
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Connection string for the database
|
|
||||||
/// </summary>
|
|
||||||
private static readonly string DbConnectionString = $"Data Source={DbFileName};";
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a header to the database
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="header">String representing the header bytes</param>
|
|
||||||
/// <param name="SHA1">SHA-1 of the deheadered file</param>
|
|
||||||
/// <param name="type">Name of the source skipper file</param>
|
|
||||||
/// <param name="debug">Enable additional log statements for debugging</param>
|
|
||||||
public static void AddHeader(string header, string SHA1, string source, bool debug)
|
|
||||||
{
|
|
||||||
// Ensure the database exists
|
|
||||||
EnsureDatabase();
|
|
||||||
|
|
||||||
// Open the database connection
|
|
||||||
SqliteConnection dbc = new(DbConnectionString);
|
|
||||||
dbc.Open();
|
|
||||||
|
|
||||||
string query = $"SELECT * FROM data WHERE sha1='{SHA1}' AND header='{header}'";
|
|
||||||
var slc = new SqliteCommand(query, dbc);
|
|
||||||
SqliteDataReader sldr = slc.ExecuteReader();
|
|
||||||
bool exists = sldr.HasRows;
|
|
||||||
|
|
||||||
if (!exists)
|
|
||||||
{
|
|
||||||
query = $"INSERT INTO data (sha1, header, type) VALUES ('{SHA1}', '{header}', '{source}')";
|
|
||||||
slc = new SqliteCommand(query, dbc);
|
|
||||||
if (debug) Console.WriteLine($"Result of inserting header: {slc.ExecuteNonQuery()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dispose of database objects
|
|
||||||
slc.Dispose();
|
|
||||||
sldr.Dispose();
|
|
||||||
dbc.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve headers from the database
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="SHA1">SHA-1 of the deheadered file</param>
|
|
||||||
/// <param name="debug">Enable additional log statements for debugging</param>
|
|
||||||
/// <returns>List of strings representing the headers to add</returns>
|
|
||||||
public static List<string> RetrieveHeaders(string SHA1, bool debug)
|
|
||||||
{
|
|
||||||
// Ensure the database exists
|
|
||||||
EnsureDatabase();
|
|
||||||
|
|
||||||
// Open the database connection
|
|
||||||
var dbc = new SqliteConnection(DbConnectionString);
|
|
||||||
dbc.Open();
|
|
||||||
|
|
||||||
// Create the output list of headers
|
|
||||||
List<string> headers = [];
|
|
||||||
|
|
||||||
string query = $"SELECT header, type FROM data WHERE sha1='{SHA1}'";
|
|
||||||
var slc = new SqliteCommand(query, dbc);
|
|
||||||
SqliteDataReader sldr = slc.ExecuteReader();
|
|
||||||
|
|
||||||
if (sldr.HasRows)
|
|
||||||
{
|
|
||||||
while (sldr.Read())
|
|
||||||
{
|
|
||||||
if (debug) Console.WriteLine($"Found match with rom type '{sldr.GetString(1)}'");
|
|
||||||
headers.Add(sldr.GetString(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine("No matching header could be found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dispose of database objects
|
|
||||||
slc.Dispose();
|
|
||||||
sldr.Dispose();
|
|
||||||
dbc.Dispose();
|
|
||||||
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ensure that the database exists and has the proper schema
|
|
||||||
/// </summary>
|
|
||||||
private static void EnsureDatabase()
|
|
||||||
{
|
|
||||||
// Make sure the file exists
|
|
||||||
if (!File.Exists(DbFileName))
|
|
||||||
File.Create(DbFileName);
|
|
||||||
|
|
||||||
// Open the database connection
|
|
||||||
SqliteConnection dbc = new(DbConnectionString);
|
|
||||||
dbc.Open();
|
|
||||||
|
|
||||||
// Make sure the database has the correct schema
|
|
||||||
string query = @"
|
|
||||||
CREATE TABLE IF NOT EXISTS data (
|
|
||||||
'sha1' TEXT NOT NULL,
|
|
||||||
'header' TEXT NOT NULL,
|
|
||||||
'type' TEXT NOT NULL,
|
|
||||||
PRIMARY KEY (sha1, header, type)
|
|
||||||
)";
|
|
||||||
SqliteCommand slc = new(query, dbc);
|
|
||||||
slc.ExecuteNonQuery();
|
|
||||||
slc.Dispose();
|
|
||||||
dbc.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using SabreTools.Hashing;
|
|
||||||
using SabreTools.IO.Extensions;
|
|
||||||
using SabreTools.Skippers;
|
|
||||||
|
|
||||||
namespace Headerer
|
|
||||||
{
|
|
||||||
internal static class Extract
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Detect header skipper compliance and create an output file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="file">Name of the file to be parsed</param>
|
|
||||||
/// <param name="outDir">Output directory to write the file to, empty means the same directory as the input file</param>
|
|
||||||
/// <param name="nostore">True if headers should not be stored in the database, false otherwise</param>
|
|
||||||
/// <param name="debug">Enable additional log statements for debugging</param>
|
|
||||||
/// <returns>True if the output file was created, false otherwise</returns>
|
|
||||||
public static bool DetectTransformStore(string file, string? outDir, bool nostore, bool debug = false)
|
|
||||||
{
|
|
||||||
// Create the output directory if it doesn't exist
|
|
||||||
if (!string.IsNullOrWhiteSpace(outDir) && !Directory.Exists(outDir))
|
|
||||||
Directory.CreateDirectory(outDir);
|
|
||||||
|
|
||||||
Console.WriteLine($"\nGetting skipper information for '{file}'");
|
|
||||||
|
|
||||||
// Get the skipper rule that matches the file, if any
|
|
||||||
SkipperMatch.Init();
|
|
||||||
Rule rule = SkipperMatch.GetMatchingRule(file, string.Empty);
|
|
||||||
|
|
||||||
// If we have an empty rule, return false
|
|
||||||
if (rule.Tests == null || rule.Tests.Length == 0 || rule.Operation != HeaderSkipOperation.None)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Console.WriteLine("File has a valid copier header");
|
|
||||||
|
|
||||||
// Get the header bytes from the file first
|
|
||||||
string hstr;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Extract the header as a string for the database
|
|
||||||
using var fs = File.OpenRead(file);
|
|
||||||
int startOffset = int.Parse(rule.StartOffset ?? "0");
|
|
||||||
byte[] hbin = new byte[startOffset];
|
|
||||||
fs.Read(hbin, 0, startOffset);
|
|
||||||
hstr = ByteArrayExtensions.ByteArrayToString(hbin)!;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the rule to the file
|
|
||||||
string newfile = string.IsNullOrWhiteSpace(outDir) ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file));
|
|
||||||
rule.TransformFile(file, newfile);
|
|
||||||
|
|
||||||
// If the output file doesn't exist, return false
|
|
||||||
if (!File.Exists(newfile))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Now add the information to the database if it's not already there
|
|
||||||
if (!nostore)
|
|
||||||
{
|
|
||||||
string sha1 = HashTool.GetFileHash(newfile, HashType.SHA1) ?? string.Empty;
|
|
||||||
Database.AddHeader(hstr, sha1, rule.SourceFile!, debug);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace Headerer
|
|
||||||
{
|
|
||||||
internal enum Feature
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
Extract,
|
|
||||||
Restore,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<!-- Assembly Properties -->
|
|
||||||
<TargetFrameworks>net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
|
||||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
|
||||||
<LangVersion>latest</LangVersion>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
||||||
<Version>1.1.2</Version>
|
|
||||||
|
|
||||||
<!-- Package Properties -->
|
|
||||||
<Authors>Matt Nadareski</Authors>
|
|
||||||
<Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright>
|
|
||||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
|
||||||
<RepositoryType>git</RepositoryType>
|
|
||||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools</RepositoryUrl>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<!-- Support All Frameworks -->
|
|
||||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
|
||||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
|
||||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
|
|
||||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
|
||||||
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.10" />
|
|
||||||
<PackageReference Include="SabreTools.Hashing" Version="1.2.2" />
|
|
||||||
<PackageReference Include="SabreTools.IO" Version="1.4.13" />
|
|
||||||
<PackageReference Include="SabreTools.Skippers" Version="1.1.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Headerer
|
|
||||||
{
|
|
||||||
internal sealed class Options
|
|
||||||
{
|
|
||||||
#region Properties
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set of input paths to use for operations
|
|
||||||
/// </summary>
|
|
||||||
public List<string> InputPaths { get; private set; } = [];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents the feature being called
|
|
||||||
/// </summary>
|
|
||||||
public Feature Feature { get; private set; } = Feature.NONE;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Output debug statements to console
|
|
||||||
/// </summary>
|
|
||||||
public bool Debug { get; private set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Optional output directory
|
|
||||||
/// </summary>
|
|
||||||
public string? OutputDir { get; private set; }
|
|
||||||
|
|
||||||
#region Extraction
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disable storing copier headers on extract
|
|
||||||
/// </summary>
|
|
||||||
public bool NoStoreHeader { get; private set; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Parse commandline arguments into an Options object
|
|
||||||
/// </summary>
|
|
||||||
public static Options? ParseOptions(string[] args)
|
|
||||||
{
|
|
||||||
// If we have invalid arguments
|
|
||||||
if (args == null || args.Length == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Create an Options object
|
|
||||||
var options = new Options();
|
|
||||||
|
|
||||||
// Get the first argument as a feature flag
|
|
||||||
string featureName = args[0];
|
|
||||||
switch (featureName)
|
|
||||||
{
|
|
||||||
case "ex":
|
|
||||||
case "extract":
|
|
||||||
options.Feature = Feature.Extract;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "re":
|
|
||||||
case "restore":
|
|
||||||
options.Feature = Feature.Restore;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Console.WriteLine($"{featureName} is not a recognized feature");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the options and paths
|
|
||||||
int index = 1;
|
|
||||||
for (; index < args.Length; index++)
|
|
||||||
{
|
|
||||||
string arg = args[index];
|
|
||||||
switch (arg)
|
|
||||||
{
|
|
||||||
case "-dbg":
|
|
||||||
case "--debug":
|
|
||||||
options.Debug = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "-o":
|
|
||||||
case "--outdir":
|
|
||||||
options.OutputDir = index + 1 < args.Length ? args[++index] : string.Empty;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#region Extraction
|
|
||||||
|
|
||||||
case "-nsh":
|
|
||||||
case "--no-store-header":
|
|
||||||
options.NoStoreHeader = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
default:
|
|
||||||
options.InputPaths.Add(arg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate we have any input paths to work on
|
|
||||||
if (options.InputPaths.Count == 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine("At least one path is required!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Display help text
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="err">Additional error text to display, can be null to ignore</param>
|
|
||||||
public static void DisplayHelp(string? err = null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(err))
|
|
||||||
Console.WriteLine($"Error: {err}");
|
|
||||||
|
|
||||||
Console.WriteLine("Headerer - Remove, store, and restore copier headers");
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine("Headerer.exe <features> <options> file|directory ...");
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine("Features:");
|
|
||||||
Console.WriteLine("ex, extract Extract and remove copier headers");
|
|
||||||
Console.WriteLine("re, restore Restore header to file based on SHA-1");
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine("Common options:");
|
|
||||||
Console.WriteLine("-?, -h, --help Display this help text and quit");
|
|
||||||
Console.WriteLine("-dbg, --debug Enable debug logging statements");
|
|
||||||
Console.WriteLine("-o, --outdir [PATH] Set output directory");
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine("Extraction options:");
|
|
||||||
Console.WriteLine("-nsh, --no-store-header Don't store the extracted header");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
namespace Headerer
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entry point for the SabreTools application
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">String array representing command line parameters</param>
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
// Validate the arguments
|
|
||||||
if (args == null || args.Length == 0)
|
|
||||||
{
|
|
||||||
Options.DisplayHelp("One input file path required");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the options from the arguments
|
|
||||||
var options = Options.ParseOptions(args);
|
|
||||||
|
|
||||||
// If we have an invalid state
|
|
||||||
if (options == null)
|
|
||||||
{
|
|
||||||
Options.DisplayHelp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through the input paths
|
|
||||||
foreach (string inputPath in options.InputPaths)
|
|
||||||
{
|
|
||||||
// TODO: Do something with the output success flags
|
|
||||||
switch (options.Feature)
|
|
||||||
{
|
|
||||||
case Feature.Extract:
|
|
||||||
_ = Extract.DetectTransformStore(inputPath, options.OutputDir, options.NoStoreHeader);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Feature.Restore:
|
|
||||||
_ = Restore.RestoreHeader(inputPath, options.OutputDir);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# SabreTools.Skippers
|
|
||||||
|
|
||||||
This library comprises of code to perform copier header operations such as matching, manipulation, and removal. These are used for many older console-based systems and helps define known header skippers for immediate use.
|
|
||||||
|
|
||||||
Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTools.Skippers).
|
|
||||||
|
|
||||||
## Headerer
|
|
||||||
|
|
||||||
A small tool that allows users to extract, store, and remove copier headers for a variety of systems. Optionally, the stored headers can be replaced on the original files using a separate command. Each of the headers are stored in a Sqlite database file that links each header to the unheadered hash of the original file. The following copier header types are supported:
|
|
||||||
|
|
||||||
* Atari 7800
|
|
||||||
* Atari Lynx
|
|
||||||
* Commodore 64 PSID music
|
|
||||||
* NEC PC-Engine / TurboGrafx 16
|
|
||||||
* Nintendo Famicom Disk System
|
|
||||||
* Nintendo Entertainment System / Famicom
|
|
||||||
* Super Nintendo Entertainment System / Super Famicom
|
|
||||||
* Super Nintendo Entertainment System / Super Famicom SPC music
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using SabreTools.Hashing;
|
|
||||||
using SabreTools.IO.Extensions;
|
|
||||||
|
|
||||||
namespace Headerer
|
|
||||||
{
|
|
||||||
internal static class Restore
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Detect and replace header(s) to the given file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="file">Name of the file to be parsed</param>
|
|
||||||
/// <param name="outDir">Output directory to write the file to, empty means the same directory as the input file</param>
|
|
||||||
/// <param name="debug">Enable additional log statements for debugging</param>
|
|
||||||
/// <returns>True if a header was found and appended, false otherwise</returns>
|
|
||||||
public static bool RestoreHeader(string file, string? outDir, bool debug = false)
|
|
||||||
{
|
|
||||||
// Create the output directory if it doesn't exist
|
|
||||||
if (!string.IsNullOrWhiteSpace(outDir) && !Directory.Exists(outDir))
|
|
||||||
Directory.CreateDirectory(outDir);
|
|
||||||
|
|
||||||
// First, get the SHA-1 hash of the file
|
|
||||||
string sha1 = HashTool.GetFileHash(file, HashType.SHA1) ?? string.Empty;
|
|
||||||
|
|
||||||
// Retrieve a list of all related headers from the database
|
|
||||||
List<string> headers = Database.RetrieveHeaders(sha1, debug);
|
|
||||||
|
|
||||||
// If we have nothing retrieved, we return false
|
|
||||||
if (headers.Count == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Now loop through and create the reheadered files, if possible
|
|
||||||
for (int i = 0; i < headers.Count; i++)
|
|
||||||
{
|
|
||||||
string outputFile = (string.IsNullOrWhiteSpace(outDir) ? $"{Path.GetFullPath(file)}.new" : Path.Combine(outDir, Path.GetFileName(file))) + i;
|
|
||||||
Console.WriteLine($"Creating reheadered file: {outputFile}");
|
|
||||||
AppendBytes(file, outputFile, ByteArrayExtensions.StringToByteArray(headers[i]), null);
|
|
||||||
Console.WriteLine("Reheadered file created!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add an aribtrary number of bytes to the inputted file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">File to be appended to</param>
|
|
||||||
/// <param name="output">Outputted file</param>
|
|
||||||
/// <param name="bytesToAddToHead">Bytes to be added to head of file</param>
|
|
||||||
/// <param name="bytesToAddToTail">Bytes to be added to tail of file</param>
|
|
||||||
private static void AppendBytes(string input, string output, byte[]? bytesToAddToHead, byte[]? bytesToAddToTail)
|
|
||||||
{
|
|
||||||
// If any of the inputs are invalid, skip
|
|
||||||
if (!File.Exists(input))
|
|
||||||
return;
|
|
||||||
|
|
||||||
using FileStream fsr = File.OpenRead(input);
|
|
||||||
using FileStream fsw = File.OpenWrite(output);
|
|
||||||
|
|
||||||
AppendBytes(fsr, fsw, bytesToAddToHead, bytesToAddToTail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add an aribtrary number of bytes to the inputted stream
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Stream to be appended to</param>
|
|
||||||
/// <param name="output">Outputted stream</param>
|
|
||||||
/// <param name="bytesToAddToHead">Bytes to be added to head of stream</param>
|
|
||||||
/// <param name="bytesToAddToTail">Bytes to be added to tail of stream</param>
|
|
||||||
private static void AppendBytes(Stream input, Stream output, byte[]? bytesToAddToHead, byte[]? bytesToAddToTail)
|
|
||||||
{
|
|
||||||
// Write out prepended bytes
|
|
||||||
if (bytesToAddToHead != null && bytesToAddToHead.Length > 0)
|
|
||||||
output.Write(bytesToAddToHead, 0, bytesToAddToHead.Length);
|
|
||||||
|
|
||||||
// Now copy the existing file over
|
|
||||||
input.CopyTo(output);
|
|
||||||
|
|
||||||
// Write out appended bytes
|
|
||||||
if (bytesToAddToTail != null && bytesToAddToTail.Length > 0)
|
|
||||||
output.Write(bytesToAddToTail, 0, bytesToAddToTail.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -68,6 +68,8 @@ A small tool that allows users to extract, store, and remove copier headers for
|
|||||||
* Super Nintendo Entertainment System / Super Famicom
|
* Super Nintendo Entertainment System / Super Famicom
|
||||||
* Super Nintendo Entertainment System / Super Famicom SPC music
|
* Super Nintendo Entertainment System / Super Famicom SPC music
|
||||||
|
|
||||||
|
This tool is no longer hosted in this repository. If you wish to use this tool, you can find it [here](https://github.com/SabreTools/SabreTools.Skippers/).
|
||||||
|
|
||||||
### RombaSharp
|
### RombaSharp
|
||||||
|
|
||||||
An in-progress tool that will try to act as a C# port of the Go-based [Romba](https://github.com/uwedeportivo/romba/) program. All features that are not already a part of SabreTools will be attempted to be added to this program. It is NOT ready for use yet. For any inquiries into the full features of this tool, please contact the project.
|
An in-progress tool that will try to act as a C# port of the Go-based [Romba](https://github.com/uwedeportivo/romba/) program. All features that are not already a part of SabreTools will be attempted to be added to this program. It is NOT ready for use yet. For any inquiries into the full features of this tool, please contact the project.
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SabreTools.Reports", "Sabre
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SabreTools.Test", "SabreTools.Test\SabreTools.Test.csproj", "{5B4E67D5-F4DA-4750-8FE2-04D08E343791}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SabreTools.Test", "SabreTools.Test\SabreTools.Test.csproj", "{5B4E67D5-F4DA-4750-8FE2-04D08E343791}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Headerer", "Headerer\Headerer.csproj", "{6629F05A-6696-4FCA-9614-83791725E499}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -130,14 +128,6 @@ Global
|
|||||||
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|x64.ActiveCfg = Release|Any CPU
|
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|x64.Build.0 = Release|Any CPU
|
{5B4E67D5-F4DA-4750-8FE2-04D08E343791}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{6629F05A-6696-4FCA-9614-83791725E499}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using SabreTools.Core;
|
using SabreTools.Core;
|
||||||
using SabreTools.Core.Filter;
|
using SabreTools.Core.Filter;
|
||||||
using SabreTools.Core.Tools;
|
using SabreTools.Core.Tools;
|
||||||
@@ -9,7 +8,6 @@ using SabreTools.FileTypes;
|
|||||||
using SabreTools.Filtering;
|
using SabreTools.Filtering;
|
||||||
using SabreTools.Hashing;
|
using SabreTools.Hashing;
|
||||||
using SabreTools.Help;
|
using SabreTools.Help;
|
||||||
using SabreTools.IO;
|
|
||||||
using SabreTools.IO.Logging;
|
using SabreTools.IO.Logging;
|
||||||
using SabreTools.Reports;
|
using SabreTools.Reports;
|
||||||
|
|
||||||
@@ -26,13 +24,6 @@ namespace SabreTools.Features
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constants
|
|
||||||
|
|
||||||
public static string HeadererFileName = Path.Combine(PathTool.GetRuntimeDirectory(), "Headerer.sqlite");
|
|
||||||
public static string HeadererConnectionString = $"Data Source={HeadererFileName};";
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Features
|
#region Features
|
||||||
|
|
||||||
#region Flag features
|
#region Flag features
|
||||||
|
|||||||
@@ -64,45 +64,6 @@ if [ $NO_BUILD = false ]; then
|
|||||||
echo "Restoring Nuget packages"
|
echo "Restoring Nuget packages"
|
||||||
dotnet restore
|
dotnet restore
|
||||||
|
|
||||||
# Build Headerer
|
|
||||||
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
|
||||||
for RUNTIME in "${RUNTIMES[@]}"; do
|
|
||||||
# Output the current build
|
|
||||||
echo "===== Build Headerer - $FRAMEWORK, $RUNTIME ====="
|
|
||||||
|
|
||||||
# If we have an invalid combination of framework and runtime
|
|
||||||
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
|
||||||
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
|
|
||||||
echo "Skipped due to invalid combination"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If we have Apple silicon but an unsupported framework
|
|
||||||
if [[ ! $(echo ${VALID_APPLE_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
|
||||||
if [ $RUNTIME = "osx-arm64" ]; then
|
|
||||||
echo "Skipped due to no Apple Silicon support"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only .NET 5 and above can publish to a single file
|
|
||||||
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]; then
|
|
||||||
# Only include Debug if building all
|
|
||||||
if [ $USE_ALL = true ]; then
|
|
||||||
dotnet publish Headerer/Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
|
|
||||||
fi
|
|
||||||
dotnet publish Headerer/Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
|
||||||
else
|
|
||||||
# Only include Debug if building all
|
|
||||||
if [ $USE_ALL = true ]; then
|
|
||||||
dotnet publish Headerer/Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
|
|
||||||
fi
|
|
||||||
dotnet publish Headerer/Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
# Build RombaSharp
|
# Build RombaSharp
|
||||||
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
||||||
for RUNTIME in "${RUNTIMES[@]}"; do
|
for RUNTIME in "${RUNTIMES[@]}"; do
|
||||||
@@ -184,38 +145,6 @@ fi
|
|||||||
|
|
||||||
# Only create archives if requested
|
# Only create archives if requested
|
||||||
if [ $NO_ARCHIVE = false ]; then
|
if [ $NO_ARCHIVE = false ]; then
|
||||||
# Create Headerer archives
|
|
||||||
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
|
||||||
for RUNTIME in "${RUNTIMES[@]}"; do
|
|
||||||
# Output the current build
|
|
||||||
echo "===== Archive Headerer - $FRAMEWORK, $RUNTIME ====="
|
|
||||||
|
|
||||||
# If we have an invalid combination of framework and runtime
|
|
||||||
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
|
||||||
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
|
|
||||||
echo "Skipped due to invalid combination"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If we have Apple silicon but an unsupported framework
|
|
||||||
if [[ ! $(echo ${VALID_APPLE_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
|
||||||
if [ $RUNTIME = "osx-arm64" ]; then
|
|
||||||
echo "Skipped due to no Apple Silicon support"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only include Debug if building all
|
|
||||||
if [ $USE_ALL = true ]; then
|
|
||||||
cd $BUILD_FOLDER/Headerer/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
|
|
||||||
zip -r $BUILD_FOLDER/Headerer_${FRAMEWORK}_${RUNTIME}_debug.zip .
|
|
||||||
fi
|
|
||||||
cd $BUILD_FOLDER/Headerer/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
|
|
||||||
zip -r $BUILD_FOLDER/Headerer_${FRAMEWORK}_${RUNTIME}_release.zip .
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create RombaSharp archives
|
# Create RombaSharp archives
|
||||||
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
||||||
for RUNTIME in "${RUNTIMES[@]}"; do
|
for RUNTIME in "${RUNTIMES[@]}"; do
|
||||||
|
|||||||
@@ -55,42 +55,6 @@ if (!$NO_BUILD.IsPresent) {
|
|||||||
Write-Host "Restoring Nuget packages"
|
Write-Host "Restoring Nuget packages"
|
||||||
dotnet restore
|
dotnet restore
|
||||||
|
|
||||||
# Build Headerer
|
|
||||||
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
|
||||||
foreach ($RUNTIME in $RUNTIMES) {
|
|
||||||
# Output the current build
|
|
||||||
Write-Host "===== Build Headerer - $FRAMEWORK, $RUNTIME ====="
|
|
||||||
|
|
||||||
# If we have an invalid combination of framework and runtime
|
|
||||||
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
|
|
||||||
Write-Host "Skipped due to invalid combination"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# If we have Apple silicon but an unsupported framework
|
|
||||||
if ($VALID_APPLE_FRAMEWORKS -notcontains $FRAMEWORK -and $RUNTIME -eq 'osx-arm64') {
|
|
||||||
Write-Host "Skipped due to no Apple Silicon support"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only .NET 5 and above can publish to a single file
|
|
||||||
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK) {
|
|
||||||
# Only include Debug if building all
|
|
||||||
if ($USE_ALL.IsPresent) {
|
|
||||||
dotnet publish Headerer\Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
|
|
||||||
}
|
|
||||||
dotnet publish Headerer\Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
# Only include Debug if building all
|
|
||||||
if ($USE_ALL.IsPresent) {
|
|
||||||
dotnet publish Headerer\Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
|
|
||||||
}
|
|
||||||
dotnet publish Headerer\Headerer.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build RombaSharp
|
# Build RombaSharp
|
||||||
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
||||||
foreach ($RUNTIME in $RUNTIMES) {
|
foreach ($RUNTIME in $RUNTIMES) {
|
||||||
@@ -166,35 +130,6 @@ if (!$NO_BUILD.IsPresent) {
|
|||||||
|
|
||||||
# Only create archives if requested
|
# Only create archives if requested
|
||||||
if (!$NO_ARCHIVE.IsPresent) {
|
if (!$NO_ARCHIVE.IsPresent) {
|
||||||
# Create Headerer archives
|
|
||||||
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
|
||||||
foreach ($RUNTIME in $RUNTIMES) {
|
|
||||||
# Output the current build
|
|
||||||
Write-Host "===== Archive Headerer - $FRAMEWORK, $RUNTIME ====="
|
|
||||||
|
|
||||||
# If we have an invalid combination of framework and runtime
|
|
||||||
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
|
|
||||||
Write-Host "Skipped due to invalid combination"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# If we have Apple silicon but an unsupported framework
|
|
||||||
if ($VALID_APPLE_FRAMEWORKS -notcontains $FRAMEWORK -and $RUNTIME -eq 'osx-arm64') {
|
|
||||||
Write-Host "Skipped due to no Apple Silicon support"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only include Debug if building all
|
|
||||||
if ($USE_ALL.IsPresent) {
|
|
||||||
Set-Location -Path $BUILD_FOLDER\Headerer\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
|
|
||||||
7z a -tzip $BUILD_FOLDER\Headerer_${FRAMEWORK}_${RUNTIME}_debug.zip *
|
|
||||||
}
|
|
||||||
|
|
||||||
Set-Location -Path $BUILD_FOLDER\Headerer\bin\Release\${FRAMEWORK}\${RUNTIME}\publish\
|
|
||||||
7z a -tzip $BUILD_FOLDER\Headerer_${FRAMEWORK}_${RUNTIME}_release.zip *
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create RombaSharp archives
|
# Create RombaSharp archives
|
||||||
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
||||||
foreach ($RUNTIME in $RUNTIMES) {
|
foreach ($RUNTIME in $RUNTIMES) {
|
||||||
|
|||||||
Reference in New Issue
Block a user