Skip to content

Commit f42b9b8

Browse files
committed
refactor
1 parent b9c6c95 commit f42b9b8

48 files changed

Lines changed: 1604 additions & 788 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55
[![MIT](https://img.shields.io/github/license/AXiX-official/UnityAsset.NET)](https://github.com/AXiX-official/UnityAsset.NET/master/LICENSE)
66
[![NuGet Stats](https://img.shields.io/nuget/v/UnityAsset.NET.svg)](https://www.nuget.org/packages/UnityAsset.NET)
77

8-
A work-in-progress .NET library for parsing/serializing/patching Unity Engine asset files.
8+
> 🚨 Major Breaking Changes in v0.2.0 🚨
9+
>
10+
> This version introduces a complete, low-level refactoring with major breaking changes.
11+
> The API is not compatible with older versions (v0.1.x).
12+
> This update aims to build a foundation that is more performant, type-safe, and provides a cleaner API.
13+
> Please read the notes below carefully before upgrading.
14+
15+
A .NET library undergoing active refactoring, currently focused on high-performance parsing and reading of Unity Engine asset files.
916

1017
Only support Unity 2017.x or later.
1118

@@ -15,19 +22,22 @@ Only support Unity 2017.x or later.
1522

1623
### BundleFile
1724

18-
- [x] Parse/Serialize
19-
- [x] Patch
20-
- [x] Calculate/Patch crc32
25+
- [x] Parsing and Reading
26+
- [ ] ~~Serialization~~ (Temporarily removed, will be re-introduced with a new API in a future version)
27+
- [ ] ~~Patching~~ (Will be re-introduced in a future version)
28+
- [ ] Calculate/Patch crc32
2129

2230
### SerializedFile
2331

24-
- [x] Parse/Serialize
25-
- [ ] Patch
32+
- [x] Parsing and Reading
33+
- [ ] ~~Serialization~~ (Temporarily removed)
34+
- [ ] ~~Patching~~ (Temporarily removed)
2635

2736
### Asset
2837

29-
- [x] Parse/Serialize
30-
- [ ] Patch
38+
- [x] Parsing based on TypeTree
39+
- [ ] ~~Serialization~~ (Temporarily removed)
40+
- [ ] ~~Patching~~ (Temporarily removed)
3141

3242
## Examples
3343

@@ -47,8 +57,9 @@ or
4757
BundleFile bf = new BundleFile( @"path to your bundlefile", "XxecodrPeGaka2e6");
4858
```
4959

50-
To remove Unity CN Encryption form File, you can simply save `BundleFile` without key
60+
~~To remove Unity CN Encryption form File, you can simply save `BundleFile` without key~~
5161
```csharp
62+
// Temporarily removed
5263
bf.Serialize(@"path to save file", CompressionType.Lz4HC, CompressionType.Lz4HC);
5364
```
5465

@@ -59,6 +70,12 @@ Some `BundleFile`'s version may be stripped, to load those file you can set a sp
5970
Setting.DefaultUnityVerion = "2020.3.48f1"
6071
```
6172

73+
## Roadmap
74+
75+
- [ ] v0.3: More Asset Class Interface.
76+
- [ ] v0.4: Re-architect and re-implement a robust and flexible serialization API.
77+
- [ ] v0.5: Re-introduce patching capabilities based on the new object model.
78+
6279
## Credits
6380

6481
---

UnityAsset.NET/Asset.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
using System.Collections.Specialized;
22
using UnityAsset.NET.Files.SerializedFiles;
33
using UnityAsset.NET.IO;
4+
using UnityAsset.NET.TypeTreeHelper;
45

56
namespace UnityAsset.NET;
67

78
public class Asset
89
{
910
public AssetFileInfo Info;
1011
public IReader RawData;
11-
public NodeData NodeData;
12+
//public NodeData NodeData;
13+
public IAsset Value;
1214

1315
public Asset(AssetFileInfo info, IReader reader)
1416
{
1517
Info = info;
16-
RawData = reader;
17-
NodeData = new NodeData(reader, info.Type.Nodes, info.Type.Nodes[0]);
18+
RawData = reader;
19+
Value = UnityObjectFactory.Create(info.Type, reader);
20+
//NodeData = new NodeData(reader, info.Type.Nodes, info.Type.Nodes[0]);
1821
}
1922
}

UnityAsset.NET/Compression/Compression.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,30 @@ public static long CompressToBytes(ReadOnlySpan<byte> uncompressedData, Span<byt
7373
throw new ArgumentException($"Unsupported compression type {compressionType}");
7474
}
7575
}
76+
77+
public static Stream CompressToStream(ReadOnlySpan<byte> uncompressedData, CompressionType compressionType)
78+
{
79+
switch (compressionType)
80+
{
81+
case CompressionType.None:
82+
return new MemoryStream(uncompressedData.ToArray());
83+
case CompressionType.Lz4:
84+
byte[] compressedData = new byte[LZ4Codec.MaximumOutputSize(uncompressedData.Length)];
85+
int compressedSize = LZ4Codec.Encode(uncompressedData, compressedData);
86+
return new MemoryStream(compressedData[..compressedSize]);
87+
case CompressionType.Lz4HC:
88+
byte[] compressedDataHC = new byte[LZ4Codec.MaximumOutputSize(uncompressedData.Length)];
89+
int compressedSizeHC = LZ4Codec.Encode(uncompressedData, compressedDataHC, LZ4Level.L12_MAX);
90+
return new MemoryStream(compressedDataHC[..compressedSizeHC]);
91+
case CompressionType.Lzma:
92+
var uncompressedStream = new MemoryStream(uncompressedData.ToArray());
93+
var encoder = new Encoder();
94+
MemoryStream compressedStream = new MemoryStream();
95+
encoder.WriteCoderProperties(compressedStream);
96+
encoder.Code(uncompressedStream, compressedStream, -1, -1, null);
97+
return compressedStream;
98+
default:
99+
throw new ArgumentException($"Unsupported compression type {compressionType}");
100+
}
101+
}
76102
}

UnityAsset.NET/Extensions/BundleFileExtensions.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,7 @@ public static void ParseFilesWithTypeConversion(this BundleFile bf)
1717
ref var file = ref filesSpan[i];
1818
if (file is { File: IReader reader, CanBeSerializedFile: true })
1919
{
20-
try
21-
{
22-
file = new FileWrapper(SerializedFile.Parse(reader), file.Info);
23-
Console.WriteLine($"File {file.Info.Path} loaded.");
24-
}
25-
catch (Exception e)
26-
{
27-
Console.WriteLine($"Error loading file {file.Info.Path}: {e.Message}");
28-
}
20+
file = new FileWrapper(SerializedFile.Parse(reader), file.Info);
2921
}
3022
}
3123
}

UnityAsset.NET/Extensions/ListExtensions.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Runtime.InteropServices;
2+
using System.Text;
23

34
namespace UnityAsset.NET.Extensions;
45

@@ -13,4 +14,17 @@ public static ReadOnlySpan<T> AsReadOnlySpan<T>(this List<T> list)
1314
{
1415
return list.AsSpan();
1516
}
17+
18+
public static string ToPlainText<T>(this List<T> list, string indent = "")
19+
{
20+
var sb = new StringBuilder();
21+
sb.AppendLine($"{indent} Array Array");
22+
sb.AppendLine($"{indent} int size = {list.Count}");
23+
for (int i = 0; i < list.Count; i++)
24+
{
25+
sb.AppendLine($"{indent} [{i}]");
26+
27+
}
28+
return sb.ToString();
29+
}
1630
}

UnityAsset.NET/Extensions/TypeTreeNodeExtensions.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,37 @@ public static class TypeTreeNodeExtensions
66
{
77
public static bool RequiresAlign(this TypeTreeNode node) => (node.MetaFlags & 0x4000) != 0;
88

9-
public static TypeTreeNode? Parent(this TypeTreeNode current, List<TypeTreeNode> nodes)
9+
public static bool RequiresAlign(this TypeTreeNode node, List<TypeTreeNode> nodes)
10+
{
11+
switch (node.Type)
12+
{
13+
case "string" :
14+
case "vector" :
15+
return node.RequiresAlign() || node.Children(nodes)[0].RequiresAlign();
16+
case "map" :
17+
return node.RequiresAlign() || node.Children(nodes)[0].Children(nodes)[1].RequiresAlign();
18+
default: return (node.MetaFlags & 0x4000) != 0;
19+
}
20+
}
21+
22+
public static TypeTreeNode Parent(this TypeTreeNode current, List<TypeTreeNode> nodes)
1023
{
1124
if (current.Index == 0)
12-
return null;
25+
throw new IndexOutOfRangeException();
1326
var nodesSpan = nodes.AsReadOnlySpan();
1427
for (int i = (int)current.Index - 1; i >= 0; i--)
1528
{
1629
if (nodesSpan[i].Level < current.Level)
1730
return nodesSpan[i];
1831
}
19-
return null;
32+
throw new IndexOutOfRangeException();
2033
}
2134

22-
public static List<TypeTreeNode>? Children(this TypeTreeNode current, List<TypeTreeNode> nodes)
35+
public static List<TypeTreeNode> Children(this TypeTreeNode current, List<TypeTreeNode> nodes)
2336
{
2437
var nodesSpan = nodes.AsReadOnlySpan();
2538
if ((int)current.Index + 1 >= nodesSpan.Length || nodesSpan[(int)current.Index + 1].Level <= current.Level)
26-
return null;
39+
return new();
2740
var children = new List<TypeTreeNode>();
2841
for (int i = (int)current.Index + 1; i < nodesSpan.Length; i++)
2942
{

UnityAsset.NET/Files/BundleFiles/BlocksAndDirectoryInfo.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Runtime.InteropServices;
2-
using System.Text;
1+
using System.Text;
32
using UnityAsset.NET.Extensions;
43
using UnityAsset.NET.IO;
54

@@ -26,7 +25,7 @@ public BlocksAndDirectoryInfo(byte[] uncompressedDataHash,
2625
reader.ReadList(reader.ReadInt32(), FileEntry.Parse)
2726
);
2827

29-
public void Serialize(IWriter writer)
28+
/*public void Serialize(IWriter writer)
3029
{
3130
writer.WriteBytes(UncompressedDataHash);
3231
writer.WriteListWithCount(BlocksInfo, (w, info) => info.Serialize(w));
@@ -35,7 +34,7 @@ public void Serialize(IWriter writer)
3534
3635
public long SerializeSize => UncompressedDataHash.Length + 8 +
3736
BlocksInfo.Sum(item => item.SerializeSize) +
38-
DirectoryInfo.Sum(item => item.SerializeSize);
37+
DirectoryInfo.Sum(item => item.SerializeSize);*/
3938

4039
public override string ToString()
4140
{

0 commit comments

Comments
 (0)