diff --git a/ArcFormats/KiriKiri/ArcXP3.cs b/ArcFormats/KiriKiri/ArcXP3.cs
index aa2f64af..94d25653 100644
--- a/ArcFormats/KiriKiri/ArcXP3.cs
+++ b/ArcFormats/KiriKiri/ArcXP3.cs
@@ -199,7 +199,6 @@ namespace GameRes.Formats.KiriKiri
entry.Cipher = crypt_algorithm.Value;
else
entry.Cipher = NoCryptAlgorithm;
- entry.IsEncrypted = !(entry.Cipher is NoCrypt);
var name = new string (header.ReadChars (name_size));
if (entry.Cipher.ObfuscatedIndex && ObfuscatedPathRe.IsMatch (name))
@@ -208,6 +207,8 @@ namespace GameRes.Formats.KiriKiri
}
entry.Name = name;
entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
+ entry.IsEncrypted = !(entry.Cipher is NoCrypt)
+ && !(entry.Cipher.StratupTjsNotEncrypted && "startup.tjs" == name);
break;
}
case 0x6d676573: // "segm"
@@ -522,13 +523,14 @@ NextEntry:
var xp3entry = new Xp3Entry {
Name = name,
- IsEncrypted = use_encryption,
Cipher = scheme,
+ IsEncrypted = use_encryption
+ && !(scheme.StratupTjsNotEncrypted && name.EndsWith ("startup.tjs"))
};
bool compress = compress_contents && ShouldCompressFile (entry);
using (var file = File.Open (name, FileMode.Open, FileAccess.Read))
{
- if (!use_encryption || 0 == file.Length)
+ if (!xp3entry.IsEncrypted || 0 == file.Length)
RawFileCopy (file, xp3entry, output, compress);
else
EncryptedFileCopy (file, xp3entry, output, compress);
@@ -787,7 +789,8 @@ NextEntry:
int read = m_stream.Read (buffer, offset, count);
if (0 != read)
{
- m_entry.Cipher.Decrypt (m_entry, m_offset, buffer, offset, read);
+ if (m_entry.IsEncrypted)
+ m_entry.Cipher.Decrypt (m_entry, m_offset, buffer, offset, read);
m_offset += read;
total += read;
offset += read;
@@ -807,7 +810,8 @@ NextEntry:
b = m_stream.ReadByte();
if (-1 != b)
{
- b = m_entry.Cipher.Decrypt (m_entry, m_offset++, (byte)b);
+ if (m_entry.IsEncrypted)
+ b = m_entry.Cipher.Decrypt (m_entry, m_offset++, (byte)b);
break;
}
NextSegment();
diff --git a/ArcFormats/KiriKiri/CryptAlgorithms.cs b/ArcFormats/KiriKiri/CryptAlgorithms.cs
index e2037eea..b60785b7 100644
--- a/ArcFormats/KiriKiri/CryptAlgorithms.cs
+++ b/ArcFormats/KiriKiri/CryptAlgorithms.cs
@@ -36,12 +36,17 @@ namespace GameRes.Formats.KiriKiri
///
public virtual bool HashAfterCrypt { get { return false; } }
+ ///
+ /// sometimes startup.tjs file is not encrypted.
+ ///
+ public bool StratupTjsNotEncrypted { get; set; }
+
///
/// whether XP3 index is obfuscated:
/// - duplicate entries
/// - entries have additional dummy segments
///
- public virtual bool ObfuscatedIndex { get { return false; } }
+ public bool ObfuscatedIndex { get; set; }
public virtual byte Decrypt (Xp3Entry entry, long offset, byte value)
{
diff --git a/ArcFormats/KiriKiri/KiriKiriCx.cs b/ArcFormats/KiriKiri/KiriKiriCx.cs
index 8446deb5..a9b8e47d 100644
--- a/ArcFormats/KiriKiri/KiriKiriCx.cs
+++ b/ArcFormats/KiriKiri/KiriKiriCx.cs
@@ -514,16 +514,6 @@ namespace GameRes.Formats.KiriKiri
}
}
- [Serializable]
- public class ZecchouCrypt : CxEncryption
- {
- public ZecchouCrypt (CxScheme scheme) : base (scheme)
- {
- }
-
- public override bool ObfuscatedIndex { get { return true; } }
- }
-
/* CxEncryption base branch order
OddBranchOrder
{