Update OPFP

This commit is contained in:
Razmoth
2023-04-30 23:10:30 +04:00
parent 7b0d563de1
commit 85ab8eec3c

View File

@@ -1,39 +1,71 @@
using System; using System;
using System.IO;
using System.Linq;
namespace AssetStudio namespace AssetStudio
{ {
public static class OPFPUtils public static class OPFPUtils
{ {
public static readonly string[] EncrytpedFolders = { "UITexture", "DynamicAtlas", "UI", "Atlas" }; private static readonly string BaseFolder = "BundleResources";
private static readonly string[] V0_Prefixes = { "UI/", "Atlas/", "UITexture/" };
private static readonly string[] V1_Prefixes = { "DynamicAtlas/", "Atlas/Skill", "Atlas/PlayerTitle", "UITexture/HeroCardEP12", "UITexture/HeroCardEP13" };
public static void Decrypt(Span<byte> data, string path) public static void Decrypt(Span<byte> data, string path)
{ {
if (IsEncryptionBundle(path, out var key)) if (IsEncryptionBundle(path, out var key, out var version))
{ {
switch (version)
{
case 0:
data[0] ^= key; data[0] ^= key;
for (int i = 1; i < data.Length; i++) for (int i = 1; i < data.Length; i++)
{ {
data[i] ^= data[i - 1]; data[i] ^= data[i - 1];
} }
break;
case 1:
for (int i = 1; i < data.Length; i++)
{
var idx = (i + data.Length + key * key) % (i + 1);
(data[i], data[idx]) = (data[idx], data[i]);
data[i] ^= key;
data[idx] ^= key;
}
break;
} }
} }
private static bool IsEncryptionBundle(string path, out byte key) }
private static bool IsEncryptionBundle(string path, out byte key, out int version)
{ {
path = path.Replace("\\", "/"); if (IsFixedPath(path, out var relativePath))
foreach(var encryptedFolder in EncrytpedFolders)
{ {
var index = path.IndexOf(encryptedFolder, 0, path.Length, StringComparison.OrdinalIgnoreCase); if (V1_Prefixes.Any(prefix => relativePath.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
if (index != -1)
{ {
var assetPath = path[index..]; key = (byte)Path.GetFileName(relativePath).Length;
if (assetPath.StartsWith(encryptedFolder, StringComparison.OrdinalIgnoreCase)) version = 1;
return true;
}
else if (V0_Prefixes.Any(prefix => relativePath.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
{ {
key = (byte)assetPath.Length; key = (byte)relativePath.Length;
version = 0;
return true; return true;
} }
} }
}
key = 0x00; key = 0x00;
version = 0;
return false;
}
private static bool IsFixedPath(string path, out string fixedPath)
{
var dirs = path.Split(Path.DirectorySeparatorChar);
if (dirs.Contains(BaseFolder))
{
var idx = Array.IndexOf(dirs, BaseFolder);
fixedPath = string.Join(Path.DirectorySeparatorChar, dirs[(idx+1)..]).Replace("\\", "/");
return true;
}
fixedPath = string.Empty;
return false; return false;
} }
} }