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 @@
+ SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=XP3Version, Mode=TwoWay, Converter={StaticResource Xp3VersionConverter}}">
+
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