This commit is contained in:
Razmoth
2023-04-01 17:51:33 +04:00
parent 29e99495de
commit c7d60450f8
25 changed files with 1077 additions and 735 deletions

View File

@@ -9,26 +9,8 @@ namespace AssetStudio
{
public static class ResourceIndex
{
public static Dictionary<int, List<int>> BundleDependencyMap;
public static Dictionary<int, Block> BlockInfoMap;
public static Dictionary<int, byte> BlockMap;
public static Dictionary<ulong, ulong> AssetMap;
public static List<Dictionary<uint, BundleInfo>> AssetLocationMap;
public static List<int> BlockSortList;
static ResourceIndex()
{
BlockSortList = new List<int>();
AssetMap = new Dictionary<ulong, ulong>();
AssetLocationMap = new List<Dictionary<uint, BundleInfo>>(0x100);
for (int i = 0; i < AssetLocationMap.Capacity; i++)
{
AssetLocationMap.Add(new Dictionary<uint, BundleInfo>(0x1FF));
}
BundleDependencyMap = new Dictionary<int, List<int>>();
BlockInfoMap = new Dictionary<int, Block>();
BlockMap = new Dictionary<int, byte>();
}
private static AssetIndex Instance = new();
private static Dictionary<uint, Dictionary<uint, string>> BundleMap = new Dictionary<uint, Dictionary<uint, string>>();
public static void FromFile(string path)
{
if (!string.IsNullOrEmpty(path))
@@ -48,11 +30,10 @@ namespace AssetStudio
var json = Encoding.UTF8.GetString(bytes);
var obj = JsonConvert.DeserializeObject<AssetIndex>(json);
if (obj != null)
{
MapToResourceIndex(obj);
}
var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
JsonConvert.PopulateObject(json, Instance, settings);
BuildBundleMap();
}
}
catch (Exception e)
@@ -64,117 +45,52 @@ namespace AssetStudio
Logger.Info("Loaded !!");
}
}
public static void Clear()
private static void BuildBundleMap()
{
BundleDependencyMap.Clear();
BlockInfoMap.Clear();
BlockMap.Clear();
AssetMap.Clear();
AssetLocationMap.ForEach(x => x.Clear());
BlockSortList.Clear();
}
public static void MapToResourceIndex(AssetIndex assetIndex)
{
BundleDependencyMap = assetIndex.Dependencies;
BlockSortList = assetIndex.SortList.ConvertAll(x => (int)x);
foreach (var asset in assetIndex.SubAssets)
foreach(var asset in Instance.Assets)
{
foreach (var subAsset in asset.Value)
if (!BundleMap.ContainsKey(asset.Value.Id))
{
var bundleInfo = new BundleInfo() { Bundle = asset.Key, Path = subAsset.Name };
AssetLocationMap[subAsset.PathHashPre].Add(subAsset.PathHashLast, bundleInfo);
AssetMap[subAsset.PathHashLast] = ((ulong)subAsset.PathHashLast) << 8 | subAsset.PathHashPre;
BundleMap[asset.Value.Id] = new Dictionary<uint, string>();
}
if (Instance.SubAssets.TryGetValue(asset.Key, out var subAssets))
{
foreach(var subAsset in subAssets)
{
BundleMap[asset.Value.Id].Add(subAsset.PathHashLast, subAsset.Name);
}
}
}
foreach (var asset in assetIndex.Assets)
}
public static void Clear()
{
Instance.Types.Clear();
Instance.SubAssets.Clear();
Instance.Dependencies.Clear();
Instance.PreloadBlocks.Clear();
Instance.PreloadShaderBlocks.Clear();
Instance.Assets.Clear();
Instance.SortList.Clear();
BundleMap.Clear();
}
public static string GetContainer(uint id, uint last)
{
if (BundleMap.TryGetValue(id, out var bundles))
{
var block = new Block() { Id = (int)asset.Value.Id, Offset = (int)asset.Value.Offset };
BlockInfoMap.Add(asset.Key, block);
if (bundles.TryGetValue(last, out var container))
{
return container;
}
}
if (!BlockMap.ContainsKey((int)asset.Value.Id))
BlockMap.Add((int)asset.Value.Id, asset.Value.Language);
}
return string.Empty;
}
public static List<BundleInfo> GetAllAssets() => AssetLocationMap.SelectMany(x => x.Values).ToList();
public static List<BundleInfo> GetAssets(int bundle) => AssetLocationMap.SelectMany(x => x.Values).Where(x => x.Bundle == bundle).ToList();
public static ulong GetAssetIndex(ulong blkHash) => AssetMap.TryGetValue(blkHash, out var value) ? value : 0;
public static Block GetBlockInfo(int bundle) => BlockInfoMap.TryGetValue(bundle, out var blk) ? blk : null;
public static BlockFile GetBlockFile(int id) => BlockMap.TryGetValue(id, out var languageCode) ? new BlockFile() { LanguageCode = languageCode, Id = id } : null;
public static int GetBlockID(int bundle) => BlockInfoMap.TryGetValue(bundle, out var block) ? block.Id : 0;
public static List<int> GetBundleDep(int bundle) => BundleDependencyMap.TryGetValue(bundle, out var dep) ? dep : new List<int>();
public static BundleInfo GetBundleInfo(ulong hash)
{
var asset = new Asset() { Hash = hash };
if (AssetLocationMap.ElementAtOrDefault(asset.Pre) != null)
if (AssetLocationMap[asset.Pre].TryGetValue(asset.Last, out var bundleInfo))
return bundleInfo;
return null;
}
public static string GetAssetPath(uint last)
{
foreach (var location in AssetLocationMap)
if (location.TryGetValue(last, out var bundleInfo))
return bundleInfo.Path;
return null;
}
public static List<uint> GetAllAssetIndices(int bundle)
{
var hashes = new List<uint>();
foreach (var location in AssetLocationMap)
foreach (var pair in location)
if (pair.Value.Bundle == bundle)
hashes.Add(pair.Key);
return hashes;
}
public static List<int> GetBundles(int id)
{
var bundles = new List<int>();
foreach (var block in BlockInfoMap)
if (block.Value.Id == id)
bundles.Add(block.Key);
return bundles;
}
public static void GetDepBundles(ref List<int> bundles)
{
for (int i = 0; i < bundles.Count; i++)
{
var bundle = bundles[i];
bundles.AddRange(GetBundleDep(bundle));
}
bundles = bundles.Distinct().ToList();
}
public static bool CheckIsLegitAssetPath(ulong hash)
{
var asset = new Asset() { Hash = hash };
return AssetLocationMap.ElementAtOrDefault(asset.Pre).ContainsKey(asset.Last);
}
}
public class BundleInfo
{
public int Bundle;
public string Path;
}
public class Asset
{
public ulong Hash;
public uint Last => (uint)(Hash >> 8);
public byte Pre => (byte)(Hash & 0xFF);
}
public class Block
{
public int Id;
public int Offset;
}
public class BlockFile
{
public int LanguageCode;
public int Id;
}
public class AssetIndex
public record AssetIndex
{
public Dictionary<string, string> Types { get; set; }
public class SubAssetInfo
public record SubAssetInfo
{
public string Name { get; set; }
public byte PathHashPre { get; set; }
@@ -184,7 +100,7 @@ namespace AssetStudio
public Dictionary<int, List<int>> Dependencies { get; set; }
public List<uint> PreloadBlocks { get; set; }
public List<uint> PreloadShaderBlocks { get; set; }
public class BlockInfo
public record BlockInfo
{
public byte Language { get; set; }
public uint Id { get; set; }
@@ -192,5 +108,16 @@ namespace AssetStudio
}
public Dictionary<int, BlockInfo> Assets { get; set; }
public List<uint> SortList { get; set; }
public AssetIndex()
{
Types = new Dictionary<string, string>();
SubAssets = new Dictionary<int, List<SubAssetInfo>>();
Dependencies = new Dictionary<int, List<int>>();
PreloadBlocks = new List<uint>();
PreloadShaderBlocks = new List<uint>();
Assets = new Dictionary<int, BlockInfo>();
SortList = new List<uint>();
}
}
}