diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..c8792a27 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: .NET Framework Build +on: [push, pull_request] +jobs: + build: + runs-on: windows-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + show-progress: false + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + # Restore NuGet packages + - name: Restore + run: nuget restore + # Build the solution + - name: Build + run: msbuild /p:Configuration=Release /p:Platform="Any CPU" /p:TargetFrameworkVersion=v4.6.2 GARbro.sln + # Publish the artifacts + - name: Publish Artifact + if: success() + uses: actions/upload-artifact@v4 + with: + name: GARbro-Mod-ci-build + path: bin/Release \ No newline at end of file diff --git a/ArcFormats/KiriKiri/ArcXP3.cs b/ArcFormats/KiriKiri/ArcXP3.cs index 6e06bd2f..b06e7c45 100644 --- a/ArcFormats/KiriKiri/ArcXP3.cs +++ b/ArcFormats/KiriKiri/ArcXP3.cs @@ -479,7 +479,7 @@ NextEntry: using (var writer = new BinaryWriter (output, Encoding.ASCII, true)) { writer.Write (s_xp3_header); - if (2 == xp3_options.Version) + if (2 == xp3_options.Version || 3 == xp3_options.Version) { writer.Write ((long)0x17); writer.Write ((int)1); @@ -516,7 +516,7 @@ NextEntry: && !(scheme.StartupTjsNotEncrypted && VFS.IsPathEqualsToFileName (name, "startup.tjs")) }; bool compress = compress_contents && ShouldCompressFile (entry); - using (var file = File.Open (name, FileMode.Open, FileAccess.Read)) + using (var file = File.Open (name, FileMode.Open, FileAccess.Read, FileShare.Read)) { if (!xp3entry.IsEncrypted || 0 == file.Length) RawFileCopy (file, xp3entry, output, compress); @@ -538,20 +538,46 @@ NextEntry: callback (callback_count++, null, arcStrings.MsgWritingIndex); long dir_pos = 0; + if (3 == xp3_options.Version) + { + foreach (var entry in dir) + { + header.Write ((uint)0x6e666e68); // "hnfn" + header.Write ((long)(4+2+entry.Name.Length*2)); + header.Write ((uint)entry.Hash); + header.Write ((short)entry.Name.Length); + foreach (char c in entry.Name) + header.Write (c); + } + dir_pos = header.BaseStream.Position; + } foreach (var entry in dir) { + var entry_name = entry.Name; + if (3 == xp3_options.Version) + { + using (var md5 = MD5.Create()) + { + var text_bytes = Encoding.Unicode.GetBytes(entry.Name.ToLowerInvariant()); + var hash = md5.ComputeHash(text_bytes); + var sb = new StringBuilder(32); + for (int i = 0; i < hash.Length; ++i) + sb.AppendFormat("{0:x2}", hash[i]); + entry_name = sb.ToString(); + } + } header.BaseStream.Position = dir_pos; header.Write ((uint)0x656c6946); // "File" long header_size_pos = header.BaseStream.Position; header.Write ((long)0); header.Write ((uint)0x6f666e69); // "info" - header.Write ((long)(4+8+8+2 + entry.Name.Length*2)); + header.Write ((long)(4+8+8+2 + entry_name.Length*2)); header.Write ((uint)(use_encryption ? 0x80000000 : 0)); header.Write ((long)entry.UnpackedSize); header.Write ((long)entry.Size); - header.Write ((short)entry.Name.Length); - foreach (char c in entry.Name) + header.Write ((short)entry_name.Length); + foreach (char c in entry_name) header.Write (c); header.Write ((uint)0x6d676573); // "segm" diff --git a/ArcFormats/KiriKiri/CreateXP3Widget.xaml b/ArcFormats/KiriKiri/CreateXP3Widget.xaml index a4c09fb0..174bc3ea 100644 --- a/ArcFormats/KiriKiri/CreateXP3Widget.xaml +++ b/ArcFormats/KiriKiri/CreateXP3Widget.xaml @@ -4,6 +4,9 @@ xmlns:s="clr-namespace:GameRes.Formats.Strings" xmlns:p="clr-namespace:GameRes.Formats.Properties" xmlns:local="clr-namespace:GameRes.Formats.GUI"> + + + @@ -14,9 +17,10 @@ diff --git a/ArcFormats/KiriKiri/CreateXP3Widget.xaml.cs b/ArcFormats/KiriKiri/CreateXP3Widget.xaml.cs index 5ea07493..84b0ba72 100644 --- a/ArcFormats/KiriKiri/CreateXP3Widget.xaml.cs +++ b/ArcFormats/KiriKiri/CreateXP3Widget.xaml.cs @@ -1,5 +1,8 @@ -using System.Windows; +using System; +using System.Globalization; +using System.Windows; using System.Windows.Controls; +using System.Windows.Data; namespace GameRes.Formats.GUI { @@ -13,4 +16,31 @@ namespace GameRes.Formats.GUI InitializeComponent (); } } + + public class Xp3VersionConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var val = (int)value; + switch (val) + { + case 1: return "1"; + case 2: return "2"; + case 3: return "Z"; + default: throw new NotImplementedException(); + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + var str = value.ToString(); + switch (str) + { + case "1": return 1; + case "2": return 2; + case "Z": return 3; + default: throw new NotImplementedException(); + } + } + } } diff --git a/ArcFormats/Resources/Formats.dat b/ArcFormats/Resources/Formats.dat index e705df8c..b53b323b 100644 Binary files a/ArcFormats/Resources/Formats.dat and b/ArcFormats/Resources/Formats.dat differ diff --git a/GARbro.sln b/GARbro.sln index 4fa25e8d..e9e89bd9 100644 --- a/GARbro.sln +++ b/GARbro.sln @@ -29,8 +29,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Image.Convert", "Image.Conv {A8865685-27CC-427B-AC38-E48D2AD05DF4} = {A8865685-27CC-427B-AC38-E48D2AD05DF4} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SchemeBuilder", "SchemeBuilder\SchemeBuilder.csproj", "{B7E7EBFB-C06E-4FC8-9AF2-7CD132AB15FD}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Experimental", "Experimental\Experimental.csproj", "{60054FD9-4472-4BB4-9E3D-2F80D3D22468}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Legacy", "Legacy\Legacy.csproj", "{C79E82A8-8D32-485D-8442-2D4F71FBB5D5}" @@ -76,10 +74,6 @@ Global {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E}.Prerelease|Any CPU.Build.0 = Prerelease|Any CPU {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E}.Release|Any CPU.ActiveCfg = Release|Any CPU {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E}.Release|Any CPU.Build.0 = Release|Any CPU - {B7E7EBFB-C06E-4FC8-9AF2-7CD132AB15FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7E7EBFB-C06E-4FC8-9AF2-7CD132AB15FD}.Prerelease|Any CPU.ActiveCfg = Prerelease|Any CPU - {B7E7EBFB-C06E-4FC8-9AF2-7CD132AB15FD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B7E7EBFB-C06E-4FC8-9AF2-7CD132AB15FD}.Release|Any CPU.Build.0 = Release|Any CPU {60054FD9-4472-4BB4-9E3D-2F80D3D22468}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {60054FD9-4472-4BB4-9E3D-2F80D3D22468}.Debug|Any CPU.Build.0 = Debug|Any CPU {60054FD9-4472-4BB4-9E3D-2F80D3D22468}.Prerelease|Any CPU.ActiveCfg = Prerelease|Any CPU