v0.90.10
This commit is contained in:
@@ -18,7 +18,9 @@ namespace AssetStudio
|
||||
{
|
||||
public static void MergeSplitAssets(string path, bool allDirectories = false)
|
||||
{
|
||||
Logger.Verbose($"Processing split assets (.splitX) prior to loading files...");
|
||||
var splitFiles = Directory.GetFiles(path, "*.split0", allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
|
||||
Logger.Verbose($"Found {splitFiles.Length} split files, attempting to merge...");
|
||||
foreach (var splitFile in splitFiles)
|
||||
{
|
||||
var destFile = Path.GetFileNameWithoutExtension(splitFile);
|
||||
@@ -27,6 +29,7 @@ namespace AssetStudio
|
||||
if (!File.Exists(destFull))
|
||||
{
|
||||
var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
|
||||
Logger.Verbose($"Creating {destFull} where split files will be combined");
|
||||
using (var destStream = File.Create(destFull))
|
||||
{
|
||||
for (int i = 0; i < splitParts.Length; i++)
|
||||
@@ -35,6 +38,7 @@ namespace AssetStudio
|
||||
using (var sourceStream = File.OpenRead(splitPart))
|
||||
{
|
||||
sourceStream.CopyTo(destStream);
|
||||
Logger.Verbose($"{splitPart} has been combined into {destFull}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +48,7 @@ namespace AssetStudio
|
||||
|
||||
public static string[] ProcessingSplitFiles(List<string> selectFile)
|
||||
{
|
||||
Logger.Verbose("Filter out paths that has .split and has the same name");
|
||||
var splitFiles = selectFile.Where(x => x.Contains(".split"))
|
||||
.Select(x => Path.Combine(Path.GetDirectoryName(x), Path.GetFileNameWithoutExtension(x)))
|
||||
.Distinct()
|
||||
@@ -61,6 +66,7 @@ namespace AssetStudio
|
||||
|
||||
public static FileReader DecompressGZip(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Decompressing GZip file {reader.FileName} into memory");
|
||||
using (reader)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
@@ -75,6 +81,7 @@ namespace AssetStudio
|
||||
|
||||
public static FileReader DecompressBrotli(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Decompressing Brotli file {reader.FileName} into memory");
|
||||
using (reader)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
@@ -89,24 +96,31 @@ namespace AssetStudio
|
||||
|
||||
public static FileReader DecryptPack(FileReader reader, Game game)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Pack encryption");
|
||||
|
||||
const int PackSize = 0x880;
|
||||
const string PackSignature = "pack";
|
||||
const string UnityFSSignature = "UnityFS";
|
||||
|
||||
var data = reader.ReadBytes((int)reader.Length);
|
||||
var idx = data.Search(PackSignature);
|
||||
if (idx == -1)
|
||||
var packIdx = data.Search(PackSignature);
|
||||
if (packIdx == -1)
|
||||
{
|
||||
Logger.Verbose($"Signature {PackSignature} was not found, aborting...");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
idx = data.Search("mr0k", idx);
|
||||
if (idx == -1)
|
||||
Logger.Verbose($"Found signature {PackSignature} at offset 0x{packIdx:X8}");
|
||||
var mr0kIdx = data.Search("mr0k", packIdx);
|
||||
if (mr0kIdx == -1)
|
||||
{
|
||||
Logger.Verbose("Signature mr0k was not found, aborting...");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
Logger.Verbose($"Found signature mr0k signature at offset 0x{mr0kIdx:X8}");
|
||||
|
||||
Logger.Verbose("Attempting to process pack chunks...");
|
||||
var ms = new MemoryStream();
|
||||
try
|
||||
{
|
||||
@@ -121,9 +135,12 @@ namespace AssetStudio
|
||||
var signature = reader.ReadStringToNull(4);
|
||||
if (signature == PackSignature)
|
||||
{
|
||||
Logger.Verbose($"Found {PackSignature} chunk at position {reader.Position - PackSignature.Length}");
|
||||
var isMr0k = reader.ReadBoolean();
|
||||
Logger.Verbose("Chunk is mr0k encrypted");
|
||||
var blockSize = BinaryPrimitives.ReadInt32LittleEndian(reader.ReadBytes(4));
|
||||
|
||||
Logger.Verbose($"Chunk size is 0x{blockSize:X8}");
|
||||
Span<byte> buffer = new byte[blockSize];
|
||||
reader.Read(buffer);
|
||||
if (isMr0k)
|
||||
@@ -134,6 +151,7 @@ namespace AssetStudio
|
||||
|
||||
if (bundleSize == 0)
|
||||
{
|
||||
Logger.Verbose("This is header chunk !! attempting to read the bundle size");
|
||||
using var blockReader = new EndianBinaryReader(new MemoryStream(buffer.ToArray()));
|
||||
var header = new Header()
|
||||
{
|
||||
@@ -144,17 +162,21 @@ namespace AssetStudio
|
||||
size = blockReader.ReadInt64()
|
||||
};
|
||||
bundleSize = header.size;
|
||||
Logger.Verbose($"Bundle size is 0x{bundleSize:X8}");
|
||||
}
|
||||
|
||||
readSize += buffer.Length;
|
||||
|
||||
if (readSize % (PackSize - 0x80) == 0)
|
||||
{
|
||||
reader.Position += PackSize - 9 - blockSize;
|
||||
var padding = PackSize - 9 - blockSize;
|
||||
reader.Position += padding;
|
||||
Logger.Verbose($"Skip 0x{padding:X8} padding");
|
||||
}
|
||||
|
||||
if (readSize == bundleSize)
|
||||
{
|
||||
Logger.Verbose($"Bundle has been read entirely !!");
|
||||
readSize = 0;
|
||||
bundleSize = 0;
|
||||
}
|
||||
@@ -166,6 +188,7 @@ namespace AssetStudio
|
||||
signature = reader.ReadStringToNull();
|
||||
if (signature == UnityFSSignature)
|
||||
{
|
||||
Logger.Verbose($"Found {UnityFSSignature} chunk at position {reader.Position - (UnityFSSignature.Length + 1)}");
|
||||
var header = new Header()
|
||||
{
|
||||
signature = reader.ReadStringToNull(),
|
||||
@@ -175,6 +198,7 @@ namespace AssetStudio
|
||||
size = reader.ReadInt64()
|
||||
};
|
||||
|
||||
Logger.Verbose($"Bundle size is 0x{header.size:X8}");
|
||||
reader.Position = pos;
|
||||
reader.BaseStream.CopyTo(ms, header.size);
|
||||
continue;
|
||||
@@ -196,15 +220,19 @@ namespace AssetStudio
|
||||
reader.Dispose();
|
||||
}
|
||||
|
||||
Logger.Verbose("Decrypted pack file successfully !!");
|
||||
ms.Position = 0;
|
||||
return new FileReader(reader.FullPath, ms);
|
||||
}
|
||||
|
||||
public static FileReader DecryptMark(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Mark encryption");
|
||||
|
||||
var signature = reader.ReadStringToNull(4);
|
||||
if (signature != "mark")
|
||||
{
|
||||
Logger.Verbose($"Expected signature mark, found {signature} instead, aborting...");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
@@ -240,6 +268,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Verbose("Decrypted mark file successfully !!");
|
||||
reader.Dispose();
|
||||
dataStream.Position = 0;
|
||||
return new FileReader(reader.FullPath, dataStream);
|
||||
@@ -247,8 +276,10 @@ namespace AssetStudio
|
||||
|
||||
public static FileReader DecryptEnsembleStar(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Ensemble Star encryption");
|
||||
if (Path.GetExtension(reader.FileName) != ".z")
|
||||
{
|
||||
Logger.Verbose($"Expected file extension .z, found {Path.GetExtension(reader.FileName)} instead, aborting...");
|
||||
return reader;
|
||||
}
|
||||
using (reader)
|
||||
@@ -269,46 +300,42 @@ namespace AssetStudio
|
||||
data[i] = (byte)(EnsembleStarKey1[k1] ^ ((size ^ EnsembleStarKey3[k3] ^ data[i] ^ EnsembleStarKey2[k2]) + remaining));
|
||||
}
|
||||
|
||||
Logger.Verbose("Decrypted Ensemble Star file successfully !!");
|
||||
return new FileReader(reader.FullPath, new MemoryStream(data));
|
||||
}
|
||||
}
|
||||
|
||||
public static FileReader ParseOPFP(FileReader reader)
|
||||
{
|
||||
var stream = reader.BaseStream;
|
||||
var data = reader.ReadBytes(0x1000);
|
||||
var idx = data.Search("UnityFS");
|
||||
if (idx != -1)
|
||||
{
|
||||
stream = new OffsetStream(stream, idx);
|
||||
}
|
||||
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
}
|
||||
|
||||
public static FileReader ParseFakeHeader(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to parse file {reader.FileName} with fake header");
|
||||
|
||||
var stream = reader.BaseStream;
|
||||
var data = reader.ReadBytes(0x1000);
|
||||
var idx = data.Search("UnityFS");
|
||||
if (idx != -1)
|
||||
{
|
||||
Logger.Verbose($"Found fake header at offset 0x{idx:X8}");
|
||||
var idx2 = data[(idx + 1)..].Search("UnityFS");
|
||||
if (idx2 != -1)
|
||||
{
|
||||
Logger.Verbose($"Found real header at offset 0x{idx + idx2 + 1:X8}");
|
||||
stream = new OffsetStream(stream, idx + idx2 + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Verbose("Real header was not found, assuming fake header is the real one");
|
||||
stream = new OffsetStream(stream, idx);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Verbose("Parsed fake header file successfully !!");
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
}
|
||||
|
||||
public static FileReader DecryptFantasyOfWind(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Fantasy of Wind encryption");
|
||||
|
||||
byte[] encryptKeyName = Encoding.UTF8.GetBytes("28856");
|
||||
const int MinLength = 0xC8;
|
||||
const int KeyLength = 8;
|
||||
@@ -319,6 +346,7 @@ namespace AssetStudio
|
||||
var signature = reader.ReadStringToNull(HeadLength);
|
||||
if (string.Compare(signature, "K9999") > 0 || reader.Length <= MinLength)
|
||||
{
|
||||
Logger.Verbose($"Signature version {signature} is higher than K9999 or stream length {reader.Length} is less than minimum length {MinLength}, aborting...");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
@@ -360,23 +388,13 @@ namespace AssetStudio
|
||||
reader.BaseStream.CopyTo(ms);
|
||||
ms.Position = 0;
|
||||
|
||||
Logger.Verbose("Decrypted Fantasy of Wind file successfully !!");
|
||||
return new FileReader(reader.FullPath, ms);
|
||||
}
|
||||
|
||||
public static FileReader ParseShiningNikki(FileReader reader)
|
||||
{
|
||||
var data = reader.ReadBytes(0x1000);
|
||||
var idx = data.Search("UnityFS");
|
||||
if (idx == -1)
|
||||
{
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
var stream = new OffsetStream(reader.BaseStream, idx);
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
}
|
||||
public static FileReader ParseHelixWaltz2(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Helix Waltz 2 encryption");
|
||||
|
||||
var originalHeader = new byte[] { 0x55, 0x6E, 0x69, 0x74, 0x79, 0x46, 0x53, 0x00, 0x00, 0x00, 0x00, 0x07, 0x35, 0x2E, 0x78, 0x2E };
|
||||
|
||||
var signature = reader.ReadStringToNull();
|
||||
@@ -384,6 +402,7 @@ namespace AssetStudio
|
||||
|
||||
if (signature != "SzxFS")
|
||||
{
|
||||
Logger.Verbose($"Expected signature SzxFS, found {signature} instead, aborting...");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
@@ -415,6 +434,7 @@ namespace AssetStudio
|
||||
data[i] = key[idx];
|
||||
}
|
||||
|
||||
Logger.Verbose("Decrypted Helix Waltz 2 file successfully !!");
|
||||
MemoryStream ms = new();
|
||||
ms.Write(originalHeader);
|
||||
ms.Write(data);
|
||||
@@ -424,6 +444,8 @@ namespace AssetStudio
|
||||
}
|
||||
public static FileReader DecryptAnchorPanic(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Anchor Panic encryption");
|
||||
|
||||
const int BlockSize = 0x800;
|
||||
|
||||
var data = reader.ReadBytes(0x1000);
|
||||
@@ -432,25 +454,31 @@ namespace AssetStudio
|
||||
var idx = data.Search("UnityFS");
|
||||
if (idx != -1)
|
||||
{
|
||||
Logger.Verbose("Found UnityFS signature, file might not be encrypted");
|
||||
return ParseFakeHeader(reader);
|
||||
}
|
||||
|
||||
var key = GetKey(Path.GetFileNameWithoutExtension(reader.FileName));
|
||||
Logger.Verbose($"Calculated key is {key}");
|
||||
|
||||
var chunkIndex = 0;
|
||||
MemoryStream ms = new();
|
||||
while (reader.Remaining > 0)
|
||||
{
|
||||
var chunkSize = Math.Min((int)reader.Remaining, BlockSize);
|
||||
Logger.Verbose($"Chunk {chunkIndex} size is {chunkSize}");
|
||||
var chunk = reader.ReadBytes(chunkSize);
|
||||
if (IsEncrypt((int)reader.Length, chunkIndex++))
|
||||
{
|
||||
Logger.Verbose($"Chunk {chunkIndex} is encrypted, decrypting...");
|
||||
RC4(chunk, key);
|
||||
}
|
||||
|
||||
ms.Write(chunk);
|
||||
}
|
||||
|
||||
Logger.Verbose("Decrypted Anchor Panic file successfully !!");
|
||||
ms.Position = 0;
|
||||
|
||||
return new FileReader(reader.FullPath, ms);
|
||||
|
||||
bool IsEncrypt(int fileSize, int chunkIndex)
|
||||
@@ -533,11 +561,14 @@ namespace AssetStudio
|
||||
|
||||
public static FileReader DecryptDreamscapeAlbireo(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Dreamscape Albireo encryption");
|
||||
|
||||
var key = new byte[] { 0x1E, 0x1E, 0x01, 0x01, 0xFC };
|
||||
|
||||
var signature = reader.ReadStringToNull(4);
|
||||
if (signature != "MJJ")
|
||||
{
|
||||
Logger.Verbose($"Expected signature MJJ, found {signature} instead, aborting...");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
@@ -559,6 +590,8 @@ namespace AssetStudio
|
||||
var sizeLow = (u5 >> 24 | (u2 << 8)) ^ u1;
|
||||
var size = (long)(sizeHigh << 32 | sizeLow);
|
||||
|
||||
Logger.Verbose($"Decrypted File info: Flag 0x{flag:X8} | Compressed blockInfo size 0x{compressedBlocksInfoSize:X8} | Decompressed blockInfo size 0x{uncompressedBlocksInfoSize:X8} | Bundle size 0x{size:X8}");
|
||||
|
||||
var blocksInfo = reader.ReadBytes((int)compressedBlocksInfoSize);
|
||||
for(int i = 0; i < blocksInfo.Length; i++)
|
||||
{
|
||||
@@ -587,6 +620,7 @@ namespace AssetStudio
|
||||
reader.BaseStream.CopyTo(ms);
|
||||
ms.Position = 0;
|
||||
|
||||
Logger.Verbose("Decrypted Dreamscape Albireo file successfully !!");
|
||||
return new FileReader(reader.FullPath, ms);
|
||||
|
||||
static uint Scrample(uint value) => (value >> 5) & 0xFFE000 | (value >> 29) | (value << 14) & 0xFF000000 | (8 * value) & 0x1FF8;
|
||||
@@ -594,6 +628,8 @@ namespace AssetStudio
|
||||
|
||||
public static FileReader DecryptImaginaryFest(FileReader reader)
|
||||
{
|
||||
Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Imaginary Fest encryption");
|
||||
|
||||
const string dataRoot = "data";
|
||||
var key = new byte[] { 0xBD, 0x65, 0xF2, 0x4F, 0xBE, 0xD1, 0x36, 0xD4, 0x95, 0xFE, 0x64, 0x94, 0xCB, 0xD3, 0x7E, 0x91, 0x57, 0xB7, 0x94, 0xB7, 0x9F, 0x70, 0xB2, 0xA9, 0xA0, 0xD5, 0x4E, 0x36, 0xC6, 0x40, 0xE0, 0x2F, 0x4E, 0x6E, 0x76, 0x6D, 0xCD, 0xAE, 0xEA, 0x05, 0x13, 0x6B, 0xA7, 0x84, 0xFF, 0xED, 0x90, 0x91, 0x15, 0x7E, 0xF1, 0xF8, 0xA5, 0x9C, 0xB6, 0xDE, 0xF9, 0x56, 0x57, 0x18, 0xBF, 0x94, 0x63, 0x6F, 0x1B, 0xE2, 0x92, 0xD2, 0x7E, 0x25, 0x95, 0x23, 0x24, 0xCB, 0x93, 0xD3, 0x36, 0xD9, 0x18, 0x11, 0xF5, 0x50, 0x18, 0xE4, 0x22, 0x28, 0xD8, 0xE2, 0x1A, 0x57, 0x1E, 0x04, 0x88, 0xA5, 0x84, 0xC0, 0x6C, 0x3B, 0x46, 0x62, 0xCE, 0x85, 0x10, 0x2E, 0xA0, 0xDC, 0xD3, 0x09, 0xB2, 0xB6, 0xA4, 0x8D, 0xAF, 0x74, 0x36, 0xF7, 0x9A, 0x3F, 0x98, 0xDA, 0x62, 0x57, 0x71, 0x75, 0x92, 0x05, 0xA3, 0xB2, 0x7C, 0xCA, 0xFB, 0x1E, 0xBE, 0xC9, 0x24, 0xC1, 0xD2, 0xB9, 0xDE, 0xE4, 0x7E, 0xF3, 0x0F, 0xB4, 0xFB, 0xA2, 0xC1, 0xC2, 0x14, 0x5C, 0x78, 0x13, 0x74, 0x41, 0x8D, 0x79, 0xF4, 0x3C, 0x49, 0x92, 0x98, 0xF2, 0xCD, 0x8C, 0x09, 0xA6, 0x40, 0x34, 0x51, 0x1C, 0x11, 0x2B, 0xE0, 0x6B, 0x42, 0x9C, 0x86, 0x41, 0x06, 0xF6, 0xD2, 0x87, 0xF1, 0x10, 0x26, 0x89, 0xC2, 0x7B, 0x2A, 0x5D, 0x1C, 0xDA, 0x92, 0xC8, 0x93, 0x59, 0xF9, 0x60, 0xD0, 0xB5, 0x1E, 0xD5, 0x75, 0x56, 0xA0, 0x05, 0x83, 0x90, 0xAC, 0x72, 0xC8, 0x10, 0x09, 0xED, 0x1A, 0x46, 0xD9, 0x39, 0x6B, 0x9E, 0x19, 0x5E, 0x51, 0x44, 0x09, 0x0D, 0x74, 0xAB, 0xA8, 0xF9, 0x32, 0x43, 0xBC, 0xD2, 0xED, 0x7B, 0x6C, 0x75, 0x32, 0x24, 0x14, 0x43, 0x5D, 0x98, 0xB2, 0xFC, 0xFB, 0xF5, 0x9A, 0x19, 0x03, 0xB0, 0xB7, 0xAC, 0xAE, 0x8B };
|
||||
|
||||
@@ -601,12 +637,14 @@ namespace AssetStudio
|
||||
var signature = Encoding.UTF8.GetString(signatureBytes[..7]);
|
||||
if (signature == "UnityFS")
|
||||
{
|
||||
Logger.Verbose("Found UnityFS signature, file might not be encrypted");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
|
||||
if (signatureBytes[7] != 0)
|
||||
{
|
||||
Logger.Verbose($"File might be encrypted with a byte xorkey 0x{signatureBytes[7]:X8}, attemping to decrypting...");
|
||||
var xorKey = signatureBytes[7];
|
||||
for (int i = 0; i < signatureBytes.Length; i++)
|
||||
{
|
||||
@@ -615,12 +653,14 @@ namespace AssetStudio
|
||||
signature = Encoding.UTF8.GetString(signatureBytes[..7]);
|
||||
if (signature == "UnityFS")
|
||||
{
|
||||
Logger.Verbose("Found UnityFS signature, key is valid, decrypting the rest of the stream");
|
||||
var remaining = reader.ReadBytes((int)reader.Remaining);
|
||||
for (int i = 0; i < remaining.Length; i++)
|
||||
{
|
||||
remaining[i] ^= xorKey;
|
||||
}
|
||||
|
||||
Logger.Verbose("Decrypted Imaginary Fest file successfully !!");
|
||||
var stream = new MemoryStream();
|
||||
stream.Write(signatureBytes);
|
||||
stream.Write(remaining);
|
||||
@@ -635,25 +675,33 @@ namespace AssetStudio
|
||||
var startIdx = Array.FindIndex(paths, x => x == dataRoot);
|
||||
if (startIdx != -1 && startIdx != paths.Length - 1)
|
||||
{
|
||||
Logger.Verbose("File is in the data folder !!");
|
||||
var path = string.Join(Path.AltDirectorySeparatorChar, paths[(startIdx+1)..]);
|
||||
var offset = GetLoadAssetBundleOffset(path);
|
||||
if (offset > 0 && offset < reader.Length)
|
||||
{
|
||||
Logger.Verbose($"Calculated offset is 0x{offset:X8}, attempting to read signature...");
|
||||
reader.Position = offset;
|
||||
signature = reader.ReadStringToNull(7);
|
||||
if (signature == "UnityFS")
|
||||
{
|
||||
Logger.Verbose($"Found UnityFS signature, file starts at 0x{offset:X8} !!");
|
||||
Logger.Verbose("Parsed Imaginary Fest file successfully !!");
|
||||
reader.Position = offset;
|
||||
return new FileReader(reader.FullPath, new MemoryStream(reader.ReadBytes((int)reader.Remaining)));
|
||||
}
|
||||
}
|
||||
Logger.Verbose($"Invalid offset, attempting to generate key...");
|
||||
reader.Position = 0;
|
||||
var data = reader.ReadBytes((int)reader.Remaining);
|
||||
var key_value = GetHashCode(path);
|
||||
Logger.Verbose($"Generated key is 0x{key_value:X8}, decrypting...");
|
||||
Decrypt(data, key_value);
|
||||
Logger.Verbose("Decrypted Imaginary Fest file successfully !!");
|
||||
return new FileReader(reader.FullPath, new MemoryStream(data));
|
||||
}
|
||||
|
||||
Logger.Verbose("File doesn't match any of the encryption types");
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user