-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port Headerer from SabreTools, add build scripts
- Loading branch information
1 parent
a5e172f
commit c19c734
Showing
12 changed files
with
876 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
name: Build and Publish | ||
|
||
on: | ||
push: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
matrix: | ||
project: [Headerer] | ||
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] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v4 | ||
with: | ||
dotnet-version: 8.0.x | ||
|
||
- name: Restore dependencies | ||
run: dotnet restore | ||
|
||
- name: Build | ||
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c Debug --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8')) && '-p:PublishSingleFile=true' || ''}} | ||
|
||
- name: Archive build | ||
run: zip -r ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip ${{ matrix.project }}/bin/Debug/${{ matrix.framework }}/${{ matrix.runtime }}/publish/ | ||
|
||
- name: Upload build | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug | ||
path: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip | ||
|
||
- name: Upload to rolling | ||
uses: ncipollo/[email protected] | ||
with: | ||
allowUpdates: True | ||
artifacts: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip | ||
body: 'Last built commit: ${{ github.sha }}' | ||
name: 'Rolling Release' | ||
prerelease: True | ||
replacesArtifacts: True | ||
tag: "rolling" | ||
updateOnlyUnreleased: True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
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(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace Headerer | ||
{ | ||
internal enum Feature | ||
{ | ||
NONE = 0, | ||
|
||
Extract, | ||
Restore, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<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> | ||
<ProjectReference Include="..\SabreTools.Skippers\SabreTools.Skippers.csproj" /> | ||
</ItemGroup> | ||
|
||
<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" /> | ||
</ItemGroup> | ||
|
||
</Project> | ||
|
Oops, something went wrong.