Skip to content

Commit

Permalink
[Sdk] Fixed issues with AssetLoader
Browse files Browse the repository at this point in the history
  • Loading branch information
wannkunstbeikor committed Oct 27, 2023
1 parent b7339bd commit 80acfca
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 90 deletions.
11 changes: 8 additions & 3 deletions FrostySdk/Interfaces/IFileInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ namespace Frosty.Sdk.Interfaces;
public interface IFileInfo
{
public bool IsComplete();

public Block<byte> GetRawData();
public Block<byte> GetData(int inOriginalSize = 0);

public Block<byte> GetData(int inOriginalSize);

protected void SerializeInternal(DataStream stream);

Expand All @@ -26,6 +26,9 @@ public static void Serialize(DataStream stream, IFileInfo fileInfo)
case KelvinFileInfo:
stream.WriteByte(1);
break;
case NonCasFileInfo:
stream.WriteByte(2);
break;
default:
throw new NotImplementedException();
}
Expand All @@ -41,6 +44,8 @@ public static IFileInfo Deserialize(DataStream stream)
return CasFileInfo.DeserializeInternal(stream);
case 1:
return KelvinFileInfo.DeserializeInternal(stream);
case 2:
return NonCasFileInfo.DeserializeInternal(stream);
default:
throw new InvalidDataException();
}
Expand Down
45 changes: 37 additions & 8 deletions FrostySdk/Managers/Infos/FileInfos/NonCasFileInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.IO;
using Frosty.Sdk.Interfaces;
using Frosty.Sdk.IO;
using Frosty.Sdk.Utils;
Expand All @@ -6,28 +7,56 @@ namespace Frosty.Sdk.Managers.Infos.FileInfos;

public class NonCasFileInfo : IFileInfo
{
public NonCasFileInfo(string inSuperBundleName, uint offset, uint size, uint logicalOffset = 0)
private string m_superBundleName;
private uint m_offset;
private uint m_size;
private uint m_logicalOffset;

public NonCasFileInfo(string inSuperBundleName, uint inOffset, uint inSize, uint inLogicalOffset = 0)
{

m_superBundleName = inSuperBundleName;
m_offset = inOffset;
m_size = inSize;
m_logicalOffset = inLogicalOffset;
}

public bool IsComplete()
{
throw new System.NotImplementedException();
return m_logicalOffset == 0;
}

public Block<byte> GetRawData()
{
throw new System.NotImplementedException();
using (FileStream stream = new(m_superBundleName, FileMode.Open, FileAccess.Read))
{
stream.Position = m_offset;

Block<byte> retVal = new((int)m_size);

stream.ReadExactly(retVal);
return retVal;
}
}

public Block<byte> GetData(int inOriginalSize = 0)
public Block<byte> GetData(int inOriginalSize)
{
throw new System.NotImplementedException();
using (BlockStream stream = BlockStream.FromFile(m_superBundleName, m_offset, (int)m_size))
{
return Cas.DecompressData(stream, inOriginalSize);
}
}

public void SerializeInternal(DataStream stream)
{
throw new System.NotImplementedException();
stream.WriteNullTerminatedString(m_superBundleName);
stream.WriteUInt32(m_offset);
stream.WriteUInt32(m_size);
stream.WriteUInt32(m_logicalOffset);
}

public static NonCasFileInfo DeserializeInternal(DataStream stream)
{
return new NonCasFileInfo(stream.ReadNullTerminatedString(), stream.ReadUInt32(), stream.ReadUInt32(),
stream.ReadUInt32());
}
}
53 changes: 29 additions & 24 deletions FrostySdk/Managers/Loaders/Dynamic2018AssetLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public BundleHelper(string inName, long inOffset, long inSize)
Size = inSize;
}
}

public void Load()
{
foreach (SuperBundleInfo sbInfo in FileSystemManager.EnumerateSuperBundles())
Expand All @@ -47,6 +47,8 @@ public void Load()
found = true;
break;
}

break;
}

if (!found)
Expand All @@ -73,23 +75,23 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
Debug.Assert(false, "We should not be here");
return Code.NotFound;
}

// check for format flags
bool isCas = toc.AsBoolean("cas");
bool isDas = toc.AsBoolean("das");

// path to sb file
string sbPath = path.Replace(".toc", ".sb");

// load bundles
if (toc.ContainsKey("bundles"))
{
// stream for loading from sb file
DataStream sbStream = BlockStream.FromFile(sbPath, false);
DataStream? baseSbStream = null;
Dictionary<int, BundleHelper>? baseBundleMapping = null;
// is its a das superBundle it stores the bundle values in lists

// is its a das superBundle it stores the bundle values in lists
if (isDas)
{
DbObjectDict bundles = toc.AsDict("bundles");
Expand All @@ -114,7 +116,7 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk

long offset = bundleObj.AsLong("offset");
long size = bundleObj.AsLong("size");

// legacy flags used until fb 2014.4.11
// cas + delta -> casPatchType for bundle members
// noncas + delta -> patched bundle and bundle members
Expand All @@ -126,7 +128,7 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
{
baseSbStream ??=
BlockStream.FromFile(FileSystemManager.ResolvePath(false, $"{inSbIc.Name}.sb"), false);

LoadBundle(baseSbStream, offset, size, ref bundle, !isCas);
}
else if (!isCas && isDelta)
Expand All @@ -135,7 +137,7 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
// we need to load the base toc to get the corresponding base bundle
baseBundleMapping ??= LoadBaseBundles(FileSystemManager.ResolvePath(false, $"{inSbIc.Name}.toc"));

if (baseBundleMapping.TryGetValue(Utils.Utils.HashString(bundle.Name), out BundleHelper helper))
if (baseBundleMapping.TryGetValue(Utils.Utils.HashString(bundle.Name, true), out BundleHelper helper))
{
baseSbStream ??=
BlockStream.FromFile(FileSystemManager.ResolvePath(false, $"{inSbIc.Name}.sb"), false);
Expand All @@ -149,6 +151,9 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
}
}
}

sbStream.Dispose();
baseSbStream?.Dispose();
}

// load chunks
Expand All @@ -166,7 +171,7 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
baseChunks.Add(obj.AsDict().AsGuid("id"));
}
}

foreach (DbObject obj in toc.AsList("chunks"))
{
DbObjectDict chunkObj = obj.AsDict();
Expand All @@ -187,7 +192,7 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
}

bool b = baseChunks.Remove(entry.Id);

AssetManager.AddSuperBundleChunk(entry);

if (entry.LogicalSize == 0)
Expand All @@ -196,15 +201,15 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk
// entry.OriginalSize = entry.FileInfo.GetOriginalSize();
}
}

Debug.Assert(baseChunks.Count == 0);
}

if (toc.ContainsKey("hasBaseBundles") || toc.ContainsKey("hasBaseChunks"))
{
/* these are never actually used, tho the newer games check for them
if (toc.ContainsKey("removedBundles"))
{
{
}
if (toc.ContainsKey("removedChunks"))
Expand All @@ -213,7 +218,7 @@ private Code LoadSuperBundle(FileSystemSource inSource, SuperBundleInstallChunk

return Code.Continue;
}

return Code.Stop;
}

Expand All @@ -225,7 +230,7 @@ private Dictionary<int, BundleHelper> LoadBaseBundles(string inPath)
{
return retVal;
}

DbObjectDict? toc = DbObject.Deserialize(inPath)?.AsDict();

if (toc is null || !toc.ContainsKey("bundles"))
Expand All @@ -236,7 +241,7 @@ private Dictionary<int, BundleHelper> LoadBaseBundles(string inPath)
foreach (DbObject obj in toc.AsList("bundles"))
{
string name = obj.AsDict().AsString("id");
retVal.Add(Utils.Utils.HashString(name), new BundleHelper(name, obj.AsDict().AsLong("offset"), obj.AsDict().AsLong("size")));
retVal.Add(Utils.Utils.HashString(name, true), new BundleHelper(name, obj.AsDict().AsLong("offset"), obj.AsDict().AsLong("size")));
}

return retVal;
Expand All @@ -257,7 +262,7 @@ private void LoadDeltaBundle(DataStream deltaStream, long inDeltaOffset, long in
}

BinaryBundle bundleMeta = DeserializeDeltaBundle(deltaStream, baseStream);

// TODO: get asset refs from sb file similar to this (https://github.com/GreyDynamics/Frostbite3_Editor/blob/develop/src/tk/greydynamics/Resource/Frostbite3/Cas/NonCasBundle.java)
// or with a cache like before
// this is just so u can load those games for now
Expand All @@ -275,7 +280,7 @@ private void LoadDeltaBundle(DataStream deltaStream, long inDeltaOffset, long in
{
AssetManager.AddChunk(chunk, bundle.Id);
}

// disable for now since we dont read the data after the bundle
// Debug.Assert(deltaStream.Position == inDeltaOffset + inDeltaSize, "Didnt read delta bundle correctly.");
// Debug.Assert((baseStream?.Position ?? 0) == inBaseOffset + inBaseSize, "Didnt read base bundle correctly.");
Expand Down Expand Up @@ -330,7 +335,7 @@ private static void LoadNonCasBundle(DataStream stream, BundleInfo bundle)
AssetManager.AddChunk(chunk, bundle.Id);
}
}

private static void LoadCasBundle(DataStream stream, BundleInfo bundle, bool isDelta)
{
DbObjectDict? bundleObj = DbObject.Deserialize(stream)?.AsDict();
Expand Down Expand Up @@ -362,7 +367,7 @@ private static void LoadCasBundle(DataStream stream, BundleInfo bundle, bool isD

IEnumerable<IFileInfo>? fileInfos =
ResourceManager.GetPatchFileInfos(entry.Sha1, deltaSha1, baseSha1);

if (fileInfos is not null)
{
entry.FileInfos.UnionWith(fileInfos);
Expand Down Expand Up @@ -445,7 +450,7 @@ private static void LoadCasBundle(DataStream stream, BundleInfo bundle, bool isD
AssetManager.AddChunk(entry, bundle.Id);
}
}

private BinaryBundle DeserializeDeltaBundle(DataStream deltaStream, DataStream? baseStream)
{
ulong magic = deltaStream.ReadUInt64();
Expand All @@ -456,17 +461,17 @@ private BinaryBundle DeserializeDeltaBundle(DataStream deltaStream, DataStream?

uint bundleSize = deltaStream.ReadUInt32(Endian.Big);
deltaStream.ReadUInt32(Endian.Big); // size of data after binary bundle

long startOffset = deltaStream.Position;

int patchedBundleSize = deltaStream.ReadInt32(Endian.Big);
uint baseBundleSize = baseStream?.ReadUInt32(Endian.Big) ?? 0;
long baseBundleOffset = baseStream?.Position ?? -1;

using (BlockStream stream = new(patchedBundleSize + 4))
{
stream.WriteInt32(patchedBundleSize, Endian.Big);

while (deltaStream.Position < bundleSize + startOffset)
{
uint packed = deltaStream.ReadUInt32(Endian.Big);
Expand Down Expand Up @@ -494,7 +499,7 @@ private BinaryBundle DeserializeDeltaBundle(DataStream deltaStream, DataStream?
{
baseStream.Position = baseBundleOffset + baseBundleSize;
}

stream.Position = 0;
return BinaryBundle.Deserialize(stream);
}
Expand Down
Loading

0 comments on commit 80acfca

Please sign in to comment.