support WARC 1.10 archives.

This commit is contained in:
morkt 2017-02-10 03:27:39 +04:00
parent c5ac986cde
commit e6ca959ded
3 changed files with 35 additions and 18 deletions

View File

@ -2,7 +2,7 @@
//! \date Fri Apr 10 03:10:42 2015
//! \brief ShiinaRio engine archive format.
//
// Copyright (C) 2015-2016 by morkt
// Copyright (C) 2015-2017 by morkt
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
@ -83,14 +83,18 @@ namespace GameRes.Formats.ShiinaRio // 椎名里緒
if (!file.View.AsciiEqual (4, " 1."))
return null;
int version = file.View.ReadByte (7) - 0x30;
if (version < 1 || version > 7)
return null;
version = 100 + version * 10;
if (170 != version && 150 != version && 140 != version && 130 != version && 120 != version)
throw new NotSupportedException ("Not supported WARC version");
uint index_offset = 0xf182ad82u ^ file.View.ReadUInt32 (8);
uint index_offset = 0xF182AD82u ^ file.View.ReadUInt32 (8);
if (index_offset >= file.MaxOffset)
return null;
var scheme = QueryEncryption (file.Name);
EncryptionScheme scheme;
if (version > 110)
scheme = QueryEncryption (file.Name);
else
scheme = EncryptionScheme.Warc110;
if (null == scheme)
return null;
var decoder = new Decoder (version, scheme);
@ -111,7 +115,7 @@ namespace GameRes.Formats.ShiinaRio // 椎名里緒
var zindex = new MemoryStream (enc_index, 8, (int)index_length-8);
index = new ZLibStream (zindex, CompressionMode.Decompress);
}
else
else if (version >= 120)
{
var unpacked = new byte[max_index_len];
index_length = UnpackRNG (enc_index, 0, index_length, unpacked);
@ -119,6 +123,10 @@ namespace GameRes.Formats.ShiinaRio // 椎名里緒
return null;
index = new MemoryStream (unpacked, 0, (int)index_length);
}
else
{
index = new MemoryStream (enc_index, 0, (int)index_length);
}
using (var header = new BinaryReader (index))
{
byte[] name_buf = new byte[decoder.EntryNameSize];
@ -151,15 +159,14 @@ namespace GameRes.Formats.ShiinaRio // 椎名里緒
var wentry = entry as WarcEntry;
if (null == warc || null == wentry || entry.Size < 8)
return arc.File.CreateStream (entry.Offset, entry.Size);
var enc_data = new byte[entry.Size];
if (entry.Size != arc.File.View.Read (entry.Offset, enc_data, 0, entry.Size))
return Stream.Null;
var enc_data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
if (enc_data.Length <= 8)
return new BinMemoryStream (enc_data, entry.Name);
uint sig = LittleEndian.ToUInt32 (enc_data, 0);
uint unpacked_size = LittleEndian.ToUInt32 (enc_data, 4);
sig ^= (unpacked_size ^ 0x82AD82) & 0xffffff;
if (entry.Size > 8)
if (warc.Decoder.WarcVersion > 110)
{
sig ^= (unpacked_size ^ 0x82AD82) & 0xFFFFFF;
if (0 != (wentry.Flags & 0x80000000u)) // encrypted entry
warc.Decoder.Decrypt (enc_data, 8, entry.Size-8);
if (warc.Decoder.ExtraCrypt != null)
@ -185,10 +192,13 @@ namespace GameRes.Formats.ShiinaRio // 椎名里緒
{
unpacked = new byte[unpacked_size];
unpack (enc_data, unpacked);
if (0 != (wentry.Flags & 0x40000000))
warc.Decoder.Decrypt2 (unpacked, 0, (uint)unpacked.Length);
if (warc.Decoder.ExtraCrypt != null)
warc.Decoder.ExtraCrypt.Decrypt (unpacked, 0, (uint)unpacked.Length, 0x204);
if (warc.Decoder.WarcVersion > 110)
{
if (0 != (wentry.Flags & 0x40000000))
warc.Decoder.Decrypt2 (unpacked, 0, (uint)unpacked.Length);
if (warc.Decoder.ExtraCrypt != null)
warc.Decoder.ExtraCrypt.Decrypt (unpacked, 0, (uint)unpacked.Length, 0x204);
}
}
return new BinMemoryStream (unpacked, entry.Name);
}

View File

@ -42,6 +42,8 @@ namespace GameRes.Formats.ShiinaRio
public byte[] DecodeBin;
public IByteArray ShiinaImage;
public IDecryptExtra ExtraCrypt;
public static readonly EncryptionScheme Warc110 = new EncryptionScheme { EntryNameSize = 0x10 };
}
public interface IByteArray
@ -136,7 +138,7 @@ namespace GameRes.Formats.ShiinaRio
void DoEncryption (byte[] data, int index, uint data_length, ContentEncryptor encryptor)
{
if (data_length < 3)
if (data_length < 3 || WarcVersion < 120)
return;
uint effective_length = Math.Min (data_length, 1024u);
int a, b;

View File

@ -254,6 +254,7 @@ Ah, Ojou-sama<br/>
Altered Pink ~Tokumu Sentai Duel Ranger~<br/>
AmairoIslenauts<br/>
Aozora Gakko no Sensei-kun<br/>
Bishuu ~Chigyaku no Mesu Dorei~<br/>
Boku to Koi Suru Ponkotsu Akuma. Suggoi Ecchi!<br/>
Cafe Sourire<br/>
Coμ<br/>
@ -276,6 +277,7 @@ Hime to Majin to Koi Suru Tamashii<br/>
Imouto Style<br/>
Inaho no Mirai<br/>
Karakara<br/>
Karenai Sekai to Owaru Hana<br/>
Kourin no Machi, Lavender no Shoujo<br/>
Kozukuri Onsen ~Ippai Tsukutte Ichizoku Hanei~<br/>
Kurenai no Tsuki<br/>
@ -383,6 +385,7 @@ Ren no Koi<br/>
<tr class="odd"><td>*.ald</td><td>-</td><td>No</td><td rowspan="6">Alice Soft</td><td rowspan="6">
Boku dake no Hokenshitsu<br/>
Daiteikoku<br/>
Majo no Shokuzai<br/>
Momoiro Guardian<br/>
Pastel Chime 3 Bind Seeker<br/>
Rance 03<br/>
@ -439,11 +442,12 @@ Shouhei-kun no Hani-Kami Life☆<br/>
Touka Gettan<br/>
</td></tr>
<tr class="odd last"><td>*</td><td><tt>\x00\x00\x04\x00</tt></td><td>No</td></tr>
<tr><td>*.war</td><td><tt>WARC 1.7</tt><br/><tt>WARC 1.5</tt><br/><tt>WARC 1.4</tt><br/><tt>WARC 1.3</tt><br/><tt>WARC 1.2</tt></td><td>No</td><td rowspan="5">Shiina Rio</td><td rowspan="5">
<tr><td>*.war</td><td><tt>WARC 1.7</tt><br/><tt>WARC 1.5</tt><br/><tt>WARC 1.4</tt><br/><tt>WARC 1.3</tt><br/><tt>WARC 1.2</tt><br/><tt>WARC 1.1</tt></td><td>No</td><td rowspan="5">Shiina Rio</td><td rowspan="5">
Ao no Juuai <span class="footnote">ShiinaRio v2.34</span><br/>
Aneiro <span class="footnote">ShiinaRio v2.49</span><br/>
Bitch Nee-chan ga Seijun na Hazu ga Nai! <span class="footnote">ShiinaRio v2.50</span><br/>
Bitch Shimai ga Seijun na Hazu ga Nai!! <span class="footnote">ShiinaRio v2.50</span><br/>
Calendar Girl <span class="footnote">ShiinaRio v2.02</span><br/>
Can Fes! ~Itazura Majo to Naisho no Gakuensai~ <span class="footnote">ShiinaRio v2.47</span><br/>
Chikan Circle <span class="footnote">ShiinaRio v2.46</span><br/>
Chikan Circle 2 <span class="footnote">ShiinaRio v2.47</span><br/>
@ -1422,6 +1426,7 @@ Ryoujoku Joshi Gakuen<br/>
<tr class="odd"><td>*</td><td><tt>BC</tt></td><td>No</td></tr>
<tr><td>*.pak</td><td><tt>Graphic PackData</tt></td><td>No</td><td rowspan="2">cromwell</td><td rowspan="2">
Ikenie Reijou<br/>
Tremolo<br/>
</td></tr>
<tr><td>*.opk</td><td><tt>VoiceOggPackFile</tt></td><td>No</td></tr>
</table>