mirror of
https://github.com/AssetRipper/AssetRipper.git
synced 2025-12-11 20:15:29 +01:00
111 lines
3.1 KiB
C#
111 lines
3.1 KiB
C#
using AssetRipper.Assets;
|
|
using AssetRipper.Assets.Bundles;
|
|
using AssetRipper.Assets.Collections;
|
|
using AssetRipper.Assets.Metadata;
|
|
using AssetRipper.IO.Files;
|
|
using AssetRipper.IO.Files.SerializedFiles;
|
|
using AssetRipper.IO.Files.Utils;
|
|
using AssetRipper.Mining.PredefinedAssets;
|
|
using AssetRipper.SourceGenerated;
|
|
using AssetRipper.Tpk;
|
|
using AssetRipper.Tpk.EngineAssets;
|
|
using Object = AssetRipper.Mining.PredefinedAssets.Object;
|
|
|
|
namespace AssetRipper.Import.Structure;
|
|
|
|
internal sealed partial record class GameInitializer
|
|
{
|
|
private static class EngineResourceInjector
|
|
{
|
|
private sealed class InjectedEngineCollection : VirtualAssetCollection
|
|
{
|
|
public InjectedEngineCollection(string name, UnityVersion version, InjectedEngineBundle bundle) : base(bundle)
|
|
{
|
|
Name = name;
|
|
Version = version;
|
|
Platform = BuildTarget.NoTarget;
|
|
Flags = TransferInstructionFlags.SerializeGameRelease | TransferInstructionFlags.IsBuiltinResourcesFile;
|
|
}
|
|
|
|
public void AddAssets(Dictionary<long, Object> assets)
|
|
{
|
|
foreach ((long pathID, Object @object) in assets)
|
|
{
|
|
IUnityObjectBase asset = AssetFactory.Create(new AssetInfo(this, pathID, @object.TypeID));
|
|
if (asset is INamed named && @object is NamedObject namedObject)
|
|
{
|
|
named.Name = namedObject.Name;
|
|
}
|
|
AddAsset(asset);
|
|
}
|
|
}
|
|
}
|
|
|
|
private sealed class InjectedEngineBundle : VirtualBundle<InjectedEngineCollection>
|
|
{
|
|
public override string Name => "Generated Engine Collections";
|
|
}
|
|
|
|
public static void InjectEngineFilesIfNecessary(GameBundle gameBundle, UnityVersion targetVersion)
|
|
{
|
|
bool injectDefaultResources = gameBundle.ResolveCollection(FilenameUtils.DefaultResourceName1) is null;
|
|
bool injectExtraResources = gameBundle.ResolveCollection(FilenameUtils.BuiltinExtraName2) is null;
|
|
if (!injectDefaultResources && !injectExtraResources)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (targetVersion == default)
|
|
{
|
|
targetVersion = gameBundle.GetMaxUnityVersion();
|
|
}
|
|
|
|
InjectedEngineBundle bundle = new();
|
|
gameBundle.AddBundle(bundle);
|
|
|
|
EngineResourceData data = GetData(targetVersion);
|
|
if (injectDefaultResources)
|
|
{
|
|
InjectedEngineCollection collection = new(FilenameUtils.DefaultResourceName1, targetVersion, bundle);
|
|
collection.AddAssets(data.DefaultResources);
|
|
}
|
|
if (injectExtraResources)
|
|
{
|
|
InjectedEngineCollection collection = new(FilenameUtils.BuiltinExtraName2, targetVersion, bundle);
|
|
collection.AddAssets(data.ExtraResources);
|
|
}
|
|
}
|
|
|
|
private static EngineResourceData GetData(UnityVersion version)
|
|
{
|
|
TpkFile tpk = TpkFile.FromStream(EngineAssetsTpk.GetStream());
|
|
TpkEngineAssetsBlob blob = (TpkEngineAssetsBlob)tpk.GetDataBlob();
|
|
if (blob.Data.Count == 0)
|
|
{
|
|
return new EngineResourceData();
|
|
}
|
|
|
|
int index;
|
|
if (version <= blob.Data[0].Key)
|
|
{
|
|
index = 0;
|
|
}
|
|
else
|
|
{
|
|
index = blob.Data.Count - 1;
|
|
for (int i = 1; i < blob.Data.Count; i++)
|
|
{
|
|
if (version <= blob.Data[i].Key)
|
|
{
|
|
index = i - 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
string json = blob.Data[index].Value;
|
|
return EngineResourceData.FromJson(json);
|
|
}
|
|
}
|
|
}
|