add snappy algorithm support of yuris engine unpack

This commit is contained in:
ichiNose
2025-03-25 14:52:00 +08:00
parent 5654485fb7
commit b25ddda701
4 changed files with 54 additions and 3 deletions

View File

@@ -31,6 +31,7 @@ using System.ComponentModel.Composition;
using GameRes.Compression;
using GameRes.Formats.Strings;
using GameRes.Utility;
using Snappy;
namespace GameRes.Formats.YuRis
{
@@ -49,6 +50,12 @@ namespace GameRes.Formats.YuRis
public uint CheckSum;
}
public enum YpfCompression
{
Zlib = 0,
Snappy = 1,
}
[Serializable]
public class YpfScheme
{
@@ -57,6 +64,7 @@ namespace GameRes.Formats.YuRis
public bool GuessKey;
public uint ExtraHeaderSize;
public uint ScriptKey;
public YpfCompression CompressType;
public YpfScheme () { }
@@ -67,6 +75,7 @@ namespace GameRes.Formats.YuRis
GuessKey = false;
ExtraHeaderSize = 0;
ScriptKey = script_key;
CompressType = YpfCompression.Zlib;
}
public YpfScheme (byte[] swap_table)
@@ -74,18 +83,27 @@ namespace GameRes.Formats.YuRis
SwapTable = swap_table;
GuessKey = true;
ExtraHeaderSize = 0;
CompressType = YpfCompression.Zlib;
}
}
public class YpfArchive : ArcFile
{
public uint ScriptKey;
public YpfCompression CompressType;
public YpfArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, uint script_key)
: base (arc, impl, dir)
{
ScriptKey = script_key;
}
public YpfArchive(ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, uint script_key, YpfCompression compress_type)
: base(arc, impl, dir)
{
ScriptKey = script_key;
CompressType = compress_type;
}
}
[Serializable]
@@ -143,7 +161,7 @@ namespace GameRes.Formats.YuRis
return null;
if (scheme.ScriptKey != 0)
return new YpfArchive (file, this, dir, scheme.ScriptKey);
return new YpfArchive (file, this, dir, scheme.ScriptKey, scheme.CompressType);
else
return new ArcFile (file, this, dir);
}
@@ -153,8 +171,33 @@ namespace GameRes.Formats.YuRis
var packed_entry = entry as PackedEntry;
var ypf = arc as YpfArchive;
Stream input = base.OpenEntry (arc, entry);
if (null != packed_entry && packed_entry.IsPacked)
input = new ZLibStream (input, CompressionMode.Decompress);
if (null != packed_entry && packed_entry.IsPacked)
{
if(ypf == null)
{
input = new ZLibStream(input, CompressionMode.Decompress);
}
else
{
switch (ypf.CompressType)
{
case YpfCompression.Snappy:
{
var compress_data = new byte[entry.Size];
input.Read(compress_data, 0, compress_data.Length);
var decomprrss_data = SnappyCodec.Uncompress(compress_data);
input = new BinMemoryStream(decomprrss_data, entry.Name);
break;
}
case YpfCompression.Zlib:
default:
{
input = new ZLibStream(input, CompressionMode.Decompress);
break;
}
}
}
}
uint unpacked_size = null == packed_entry ? entry.Size : packed_entry.UnpackedSize;
if (null == ypf || 0 == ypf.ScriptKey || unpacked_size <= 0x20
|| !entry.Name.HasExtension (".ybn"))