Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit ae2bbff

Browse files
committed
Update
1 parent 8ab1067 commit ae2bbff

File tree

5 files changed

+193
-82
lines changed

5 files changed

+193
-82
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
##
44
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
55

6+
oo2core_8_win64.dll
67
*.zip
78

89
# User-specific files

LibBundle/BundleContainer.cs

+134-39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
using System;
2+
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
24
using System.IO;
5+
using System.Linq;
6+
using System.Threading;
7+
using System.Threading.Tasks;
38

49
namespace LibBundle
510
{
@@ -42,6 +47,7 @@ public enum COMPRESSTION_LEVEL
4247

4348
public string path;
4449
public long offset;
50+
public COMPRESSTION_LEVEL Compression_Level = COMPRESSTION_LEVEL.Normal;
4551

4652
public int uncompressed_size;
4753
public int compressed_size;
@@ -117,48 +123,138 @@ public virtual MemoryStream Read(BinaryReader br)
117123
var chunks = new int[entry_count];
118124
for (int i = 0; i < entry_count; i++)
119125
chunks[i] = br.ReadInt32();
120-
126+
127+
var compressed = new byte[entry_count][];
128+
for (int i = 0; i < entry_count; i++)
129+
compressed[i] = br.ReadBytes(chunks[i]);
130+
131+
Parallel.For(0, entry_count, i => {
132+
var size = (i + 1 == entry_count) ? uncompressed_size - (chunk_size * (entry_count - 1)) : chunk_size; // isLast ?
133+
var toSave = new byte[size + 64];
134+
OodleLZ_Decompress(compressed[i], compressed[i].Length, toSave, size, 0, 0, 0, IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, 3);
135+
compressed[i] = toSave.Take(size).ToArray();
136+
});
137+
121138
var data = new MemoryStream(uncompressed_size);
122139
for (int i = 0; i < entry_count; i++)
140+
data.Write(compressed[i]);
141+
142+
return data;
143+
}
144+
145+
public virtual byte[] AppendAndSave(Stream newData, string path = null)
146+
{
147+
if (path == null)
148+
path = this.path;
149+
offset = 0;
150+
return AppendAndSave(newData, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
151+
}
152+
153+
public virtual byte[] AppendAndSave(Stream newData, Stream originalData)
154+
{
155+
originalData.Seek(offset + 60, SeekOrigin.Begin);
156+
var OldChunkCompressedSizes = new byte[(entry_count - 1) * 4];
157+
originalData.Read(OldChunkCompressedSizes);
158+
159+
var lastCunkCompressedSize = originalData.ReadByte() | originalData.ReadByte() << 8 | originalData.ReadByte() << 16 | originalData.ReadByte() << 24; // ReadInt32
160+
161+
var lastCunkDecompressedSize = uncompressed_size - (chunk_size * (entry_count - 1));
162+
163+
uncompressed_size = (int)(size_decompressed += newData.Length);
164+
entry_count = uncompressed_size / chunk_size;
165+
if (uncompressed_size % chunk_size != 0) entry_count++;
166+
head_size = entry_count * 4 + 48;
167+
168+
var msToSave = new MemoryStream();
169+
var bw = new BinaryWriter(msToSave);
170+
171+
msToSave.Seek(60 + (entry_count * 4), SeekOrigin.Begin);
172+
var o = new byte[compressed_size - lastCunkCompressedSize];
173+
originalData.Read(o);
174+
bw.Write(o);
175+
176+
var lastChunkCompressedData = new byte[lastCunkCompressedSize];
177+
originalData.Read(lastChunkCompressedData);
178+
var lastCunkDecompressedData = new byte[lastCunkDecompressedSize + 64];
179+
OodleLZ_Decompress(lastChunkCompressedData, lastCunkCompressedSize, lastCunkDecompressedData, lastCunkDecompressedSize, 0, 0, 0, IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, 3);
180+
181+
newData.Seek(0, SeekOrigin.Begin);
182+
compressed_size -= lastCunkCompressedSize;
183+
var NewChunkCompressedSizes = new int[entry_count - (OldChunkCompressedSizes.Length / 4)];
184+
185+
var FirstNewDataChunk = new byte[Math.Min(chunk_size - lastCunkDecompressedSize, newData.Length)];
186+
newData.Read(FirstNewDataChunk);
187+
FirstNewDataChunk = lastCunkDecompressedData.Take(lastCunkDecompressedSize).Concat(FirstNewDataChunk).ToArray(); // Decompressed
188+
var CompressedChunk = new byte[FirstNewDataChunk.Length + 548];
189+
var CompressedLength = OodleLZ_Compress(encoder, FirstNewDataChunk, FirstNewDataChunk.Length, CompressedChunk, Compression_Level, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
190+
compressed_size += NewChunkCompressedSizes[0] = CompressedLength;
191+
bw.Write(CompressedChunk, 0, CompressedLength); // Compressed
192+
var byteArrays = new byte[NewChunkCompressedSizes.Length][];
193+
for (int i = 1; i < NewChunkCompressedSizes.Length; i++)
123194
{
124-
var b = br.ReadBytes(chunks[i]);
125-
int size = (i + 1 == entry_count) ? uncompressed_size - (chunk_size * (entry_count - 1)) : chunk_size; // isLast ?
126-
var toSave = new byte[size + 64];
127-
OodleLZ_Decompress(b, b.Length, toSave, size, 0, 0, 0, IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, 3);
128-
data.Write(toSave, 0, size);
195+
var size = (i + 1 == NewChunkCompressedSizes.Length) ? uncompressed_size - (chunk_size * (entry_count - 1)) : chunk_size;
196+
newData.Read(byteArrays[i] = new byte[size]);
129197
}
130-
return data;
198+
Parallel.For(1, NewChunkCompressedSizes.Length, i => {
199+
var by = new byte[byteArrays[i].Length + 548];
200+
var l = OodleLZ_Compress(encoder, byteArrays[i], byteArrays[i].Length, by, Compression_Level, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
201+
byteArrays[i] = by;
202+
Interlocked.Add(ref compressed_size, NewChunkCompressedSizes[i] = l);
203+
});
204+
for (int i = 0; i < NewChunkCompressedSizes.Length - 1; i++)
205+
bw.Write(byteArrays[i], 0, NewChunkCompressedSizes[i]);
206+
207+
size_compressed = compressed_size;
208+
209+
msToSave.Seek(60, SeekOrigin.Begin);
210+
bw.Write(OldChunkCompressedSizes);
211+
for (int i = 0; i < NewChunkCompressedSizes.Length; i++)
212+
bw.Write(NewChunkCompressedSizes[i]);
213+
214+
msToSave.Seek(0, SeekOrigin.Begin);
215+
bw.Write(uncompressed_size);
216+
bw.Write(compressed_size);
217+
bw.Write(head_size);
218+
bw.Write((uint)encoder);
219+
bw.Write(unknown);
220+
bw.Write(size_decompressed);
221+
bw.Write(size_compressed);
222+
bw.Write(entry_count);
223+
bw.Write(chunk_size);
224+
bw.Write(unknown3);
225+
bw.Write(unknown4);
226+
bw.Write(unknown5);
227+
bw.Write(unknown6);
228+
229+
bw.Flush();
230+
var result = msToSave.ToArray();
231+
bw.Close();
232+
return result;
131233
}
132234

133235
//Packing
134-
public virtual void Save(Stream ms, string path)
236+
public virtual void Save(Stream newData, string path)
135237
{
136238
var bw = new BinaryWriter(File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite));
137239

138-
uncompressed_size = (int)(size_decompressed = ms.Length);
240+
uncompressed_size = (int)(size_decompressed = newData.Length);
139241
entry_count = uncompressed_size / chunk_size;
140242
if (uncompressed_size % chunk_size != 0) entry_count++;
141243
head_size = entry_count * 4 + 48;
142244

143245
bw.BaseStream.Seek(60 + (entry_count * 4), SeekOrigin.Begin);
144-
ms.Position = 0;
246+
newData.Seek(0, SeekOrigin.Begin);
145247
compressed_size = 0;
146248
var chunks = new int[entry_count];
147-
for (int i = 0; i < entry_count - 1; i++)
249+
for (int i = 0; i < entry_count; i++)
148250
{
149-
var b = new byte[chunk_size];
150-
ms.Read(b, 0, chunk_size);
251+
var b = new byte[i + 1 == entry_count ? uncompressed_size - (entry_count - 1) * chunk_size : chunk_size];
252+
newData.Read(b, 0, b.Length);
151253
var by = new byte[b.Length + 548];
152-
var l = OodleLZ_Compress(ENCODE_TYPES.LEVIATHAN, b, b.Length, by, COMPRESSTION_LEVEL.Normal, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
254+
var l = OodleLZ_Compress(encoder, b, b.Length, by, Compression_Level, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
153255
compressed_size += chunks[i] = l;
154256
bw.Write(by, 0, l);
155257
}
156-
var b2 = new byte[ms.Length - (entry_count - 1) * chunk_size];
157-
ms.Read(b2, 0, b2.Length);
158-
var by2 = new byte[b2.Length + 548];
159-
var l2 = OodleLZ_Compress(ENCODE_TYPES.LEVIATHAN, b2, b2.Length, by2, COMPRESSTION_LEVEL.Normal, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
160-
compressed_size += chunks[entry_count - 1] = l2;
161-
bw.Write(by2, 0, l2);
162258
size_compressed = compressed_size;
163259

164260
bw.BaseStream.Seek(60, SeekOrigin.Begin);
@@ -184,42 +280,41 @@ public virtual void Save(Stream ms, string path)
184280
bw.Close();
185281
}
186282
//Packing
187-
public virtual byte[] Save(Stream ms)
283+
public virtual byte[] Save(Stream newData)
188284
{
189285
var msToSave = new MemoryStream();
190286
var bw = new BinaryWriter(msToSave);
191287

192-
uncompressed_size = (int)(size_decompressed = ms.Length);
288+
uncompressed_size = (int)(size_decompressed = newData.Length);
193289
entry_count = uncompressed_size / chunk_size;
194290
if (uncompressed_size % chunk_size != 0) entry_count++;
195291
head_size = entry_count * 4 + 48;
196292

197-
bw.BaseStream.Seek(60 + (entry_count * 4), SeekOrigin.Begin);
198-
ms.Position = 0;
293+
msToSave.Seek(60 + (entry_count * 4), SeekOrigin.Begin);
294+
newData.Seek(0, SeekOrigin.Begin);
199295
compressed_size = 0;
200296
var chunks = new int[entry_count];
201-
for (int i = 0; i < entry_count - 1; i++)
297+
var byteArrays = new byte[entry_count][];
298+
for (int i = 0; i < entry_count; i++)
202299
{
203-
var b = new byte[chunk_size];
204-
ms.Read(b, 0, chunk_size);
205-
var by = new byte[b.Length + 548];
206-
var l = OodleLZ_Compress(ENCODE_TYPES.LEVIATHAN, b, b.Length, by, COMPRESSTION_LEVEL.Normal, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
207-
compressed_size += chunks[i] = l;
208-
bw.Write(by, 0, l);
300+
var b = new byte[i + 1 == entry_count ? uncompressed_size - (entry_count - 1) * chunk_size : chunk_size];
301+
newData.Read(byteArrays[i] = b);
209302
}
210-
var b2 = new byte[ms.Length - (entry_count - 1) * chunk_size];
211-
ms.Read(b2, 0, b2.Length);
212-
var by2 = new byte[b2.Length + 548];
213-
var l2 = OodleLZ_Compress(ENCODE_TYPES.LEVIATHAN, b2, b2.Length, by2, COMPRESSTION_LEVEL.Normal, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
214-
compressed_size += chunks[entry_count - 1] = l2;
215-
bw.Write(by2, 0, l2);
303+
Parallel.For(0, entry_count, i => {
304+
var by = new byte[byteArrays[i].Length + 548];
305+
var l = OodleLZ_Compress(encoder, byteArrays[i], byteArrays[i].Length, by, Compression_Level, IntPtr.Zero, 0, 0, IntPtr.Zero, 0);
306+
byteArrays[i] = by;
307+
Interlocked.Add(ref compressed_size, chunks[i] = l);
308+
});
216309
size_compressed = compressed_size;
310+
for (int i = 0; i < entry_count; i++)
311+
bw.Write(byteArrays[i], 0, chunks[i]);
217312

218-
bw.BaseStream.Seek(60, SeekOrigin.Begin);
313+
msToSave.Seek(60, SeekOrigin.Begin);
219314
for (int i = 0; i < entry_count; i++)
220315
bw.Write(chunks[i]);
221316

222-
bw.BaseStream.Seek(0, SeekOrigin.Begin);
317+
msToSave.Seek(0, SeekOrigin.Begin);
223318
bw.Write(uncompressed_size);
224319
bw.Write(compressed_size);
225320
bw.Write(head_size);

LibBundle/IndexContainer.cs

+10-11
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ public IndexContainer(BinaryReader br)
4141
var f = new FileRecord(databr);
4242
Files[i] = f;
4343
FindFiles[f.Hash] = f;
44-
f.bundleRecord = Bundles[f.BundleIndex];
45-
Bundles[f.BundleIndex].Files.Add(f);
44+
var b = Bundles[f.BundleIndex];
45+
f.bundleRecord = b;
46+
b.Files.Add(f);
47+
if (f.Offset >= b.validSize) b.validSize = f.Offset + f.Size;
4648
}
4749

4850
int directoryCount = databr.ReadInt32();
@@ -103,8 +105,8 @@ public virtual void Save(string path)
103105
bw.Write(Bundles.Length);
104106
foreach (var b in Bundles)
105107
{
106-
bw.Write(b.nameLength);
107-
bw.Write(Encoding.UTF8.GetBytes(b.Name), 0, b.nameLength);
108+
bw.Write(b.NameLength);
109+
bw.Write(Encoding.UTF8.GetBytes(b.Name), 0, b.NameLength);
108110
bw.Write(b.UncompressedSize);
109111
}
110112
bw.Write(Files.Length);
@@ -135,8 +137,8 @@ public virtual byte[] Save()
135137
bw.Write(Bundles.Length);
136138
foreach (var b in Bundles)
137139
{
138-
bw.Write(b.nameLength);
139-
bw.Write(Encoding.UTF8.GetBytes(b.Name), 0, b.nameLength);
140+
bw.Write(b.NameLength);
141+
bw.Write(Encoding.UTF8.GetBytes(b.Name), 0, b.NameLength);
140142
bw.Write(b.UncompressedSize);
141143
}
142144
bw.Write(Files.Length);
@@ -178,11 +180,8 @@ public BundleRecord GetSmallestBundle(IList<BundleRecord> Bundles = null)
178180

179181
public static ulong FNV1a64Hash(string str)
180182
{
181-
if (str.EndsWith("/"))
182-
{
183-
str.TrimEnd(new char[] { '/' });
184-
str += "++";
185-
}
183+
if (str.EndsWith('/'))
184+
str = str.TrimEnd(new char[] { '/' }) + "++";
186185
else
187186
str = str.ToLower() + "++";
188187

LibBundle/LibBundle.csproj

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<TargetFramework>net5.0</TargetFramework>
55
<Copyright>Copyright © 2020 aianlinb</Copyright>
6-
<AssemblyVersion>2.2.0.2</AssemblyVersion>
6+
<AssemblyVersion>2.3.0.0</AssemblyVersion>
7+
<OutputType>Library</OutputType>
78
</PropertyGroup>
89

910
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
1011
<DefineConstants>DEBUG;TRACE</DefineConstants>
1112
<PlatformTarget>x64</PlatformTarget>
12-
<Optimize>true</Optimize>
13+
<Optimize>false</Optimize>
1314
<OutputPath>..\Release</OutputPath>
1415
<DebugType>full</DebugType>
16+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
17+
</PropertyGroup>
18+
19+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
20+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1521
</PropertyGroup>
1622

1723
<ItemGroup>

0 commit comments

Comments
 (0)