Skip to content

Commit 8586d0f

Browse files
committed
Calculate/Patch crc32
1 parent cd5a3bd commit 8586d0f

4 files changed

Lines changed: 48 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Only support Unity 2017.x or later.
1818
- [x] Parsing and Reading
1919
- [x] Serialization
2020
- [ ] ~~Patching~~ (Will be re-introduced in a future version)
21-
- [ ] Calculate/Patch crc32
21+
- [x] Calculate/Patch crc32
2222

2323
### SerializedFile
2424

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using UnityAsset.NET.Files;
2+
using UnityAsset.NET.Files.BundleFiles;
23
using UnityAsset.NET.Files.SerializedFiles;
4+
using UnityAsset.NET.IO;
5+
using UnityAsset.NET.IO.Reader;
36

47
namespace UnityAsset.NET.Extensions;
58

@@ -11,12 +14,35 @@ public static List<Asset> Assets(this BundleFile bf) =>
1114
.SelectMany(file => ((SerializedFile)file.File).Assets)
1215
.ToList();
1316

14-
/*public static void PatchCrc32(this BundleFile bf, uint newCrc32)
17+
public static uint CalculateCrc32(this BundleFile bf)
1518
{
16-
if (bf.Crc32 != newCrc32)
19+
if (bf.Files.Any(file => file.File is not IReaderProvider))
20+
throw new ArgumentException("The bundle file must contain at least one IReaderProvider.");
21+
22+
var buffer = new byte[8092];
23+
uint crc = 0;
24+
foreach (var file in bf.Files)
1725
{
18-
var patchBytes = CRC32.rCRC(newCrc32, bf.Crc32);
19-
bf.Files.Add(new FileWrapper(new DataBuffer(patchBytes), new FileEntry(0, 4, 0, "crc32-patch-data")));
26+
var rp = (IReaderProvider)file.File;
27+
var reader = rp.CreateReader();
28+
while (reader.Remaining > 0)
29+
{
30+
var bytesRead = reader.Read(buffer, 0, 8092);
31+
crc = CRC32.CalculateCRC32(buffer.AsSpan(0, bytesRead), crc);
32+
}
2033
}
21-
}*/
34+
35+
return crc;
36+
}
37+
38+
public static void PatchCrc32(this BundleFile bf, uint newCrc32)
39+
{
40+
var oldCrc = bf.CalculateCrc32();
41+
if (newCrc32 == oldCrc)
42+
return;
43+
var patch = CRC32.rCRC(oldCrc, newCrc32);
44+
var offset = bf.Files[^1].Info.Offset + bf.Files[^1].Info.Size;
45+
var entry = new FileEntry(offset, (ulong)patch.Length, 0, "crc32Patch");
46+
bf.Files.Add(new (new MemoryReaderProvider(patch), entry));
47+
}
2248
}

UnityAsset.NET/Files/BundleFiles/BundleFile.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public class BundleFile : IFile
3333
/// Optional key for UnityCN encryption
3434
/// </summary>
3535
public readonly string? UnityCnKey;
36-
37-
public uint? Crc32;
3836

3937
public IVirtualFileInfo? SourceVirtualFile { get; private set; }
4038

UnityAsset.NET/IO/Reader/MemoryReader.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,20 @@ public string ReadNullTerminatedString()
130130

131131
// TEMPORARY: make it writable
132132
public Span<byte> AsWritableSpan => _data.Span;
133+
}
134+
135+
public class MemoryReaderProvider : IReaderProvider
136+
{
137+
private readonly Memory<byte> _data;
138+
public MemoryReaderProvider(byte[] data)
139+
{
140+
_data = new Memory<byte>(data);
141+
}
142+
143+
public MemoryReaderProvider(Memory<byte> data)
144+
{
145+
_data = data;
146+
}
147+
148+
public IReader CreateReader(Endianness endian = Endianness.BigEndian) => new MemoryReader(_data, 0, endian);
133149
}

0 commit comments

Comments
 (0)