mirror of
https://github.com/AssetRipper/Tpk.git
synced 2026-11-13 20:05:48 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f94757d204 | ||
|
|
474fe30489 | ||
|
|
70c3b6ca93 | ||
|
|
6b72bf855d | ||
|
|
be9d53f317 | ||
|
|
a7e3d89b2d | ||
|
|
21eca606fd | ||
|
|
8bef636a8f | ||
|
|
7ed791b58c | ||
|
|
236236fed8 | ||
|
|
019d733bb2 | ||
|
|
7663a53449 | ||
|
|
f9e25d911f | ||
|
|
a4f6013e45 | ||
|
|
1b0a2b3082 | ||
|
|
b5b5ace321 |
No files matched your search
@@ -27,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Tpk Repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
run: dotnet build /p:Configuration=Release
|
||||
working-directory: ./Tpk.ConsoleApp/
|
||||
- name: Checkout DocumentationDumps Repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: 'AssetRipper/DocumentationDumps'
|
||||
path: DocumentationDumps
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Tpk Repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
run: dotnet build /p:Configuration=Release
|
||||
working-directory: ./Tpk.ConsoleApp/
|
||||
- name: Checkout TypeTreeDumps Repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: 'AssetRipper/TypeTreeDumps'
|
||||
sparse-checkout: 'InfoJson'
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<Authors>ds5678</Authors>
|
||||
<Company>AssetRipper</Company>
|
||||
<VersionPrefix>1.2.0</VersionPrefix>
|
||||
<VersionPrefix>2.0.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/AssetRipper/Tpk</RepositoryUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
<AssemblyName>AssetRipper.Tpk.ConsoleApp</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SharpCompress" Version="0.47.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tpk.TypeTrees.Json\Tpk.TypeTrees.Json.csproj" />
|
||||
<ProjectReference Include="..\Tpk\Tpk.csproj" />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AssetRipper.Primitives;
|
||||
using AssetRipper.Tpk.Shared;
|
||||
using AssetRipper.Tpk.TypeTrees;
|
||||
using AssetRipper.Tpk.TypeTrees.Json;
|
||||
using System.Collections.Generic;
|
||||
@@ -28,44 +29,37 @@ namespace AssetRipper.Tpk.ConsoleApp
|
||||
|
||||
private static TpkTypeTreeBlob Create(IEnumerable<string> pathsOrderedByUnityVersion)
|
||||
{
|
||||
return Create(pathsOrderedByUnityVersion.Select(path => UnityInfo.ReadFromJsonFile(path)));
|
||||
return Create(pathsOrderedByUnityVersion.Select(path =>
|
||||
{
|
||||
string versionString = Path.GetFileNameWithoutExtension(path);
|
||||
UnityVersion version = UnityVersion.Parse(versionString);
|
||||
UnityInfo info = UnityInfo.ReadFromJsonFile(path);
|
||||
return (version, info);
|
||||
}));
|
||||
}
|
||||
|
||||
private static TpkTypeTreeBlob Create(IEnumerable<UnityInfo> infosOrderedByUnityVersion)
|
||||
private static TpkTypeTreeBlob Create(IEnumerable<(UnityVersion Version, UnityInfo Info)> infosOrderedByUnityVersion)
|
||||
{
|
||||
TpkTypeTreeBlob blob = new TpkTypeTreeBlob();
|
||||
blob.CommonString.Add(UnityVersion.MinVersion, 0);
|
||||
|
||||
byte latestCommonStringCount = 0;
|
||||
List<string> commonStrings = new List<string>();
|
||||
Dictionary<int, string> latestUnityClassesDumped = new Dictionary<int, string>();
|
||||
Dictionary<int, TpkClassInformation> classDictionary = new Dictionary<int, TpkClassInformation>();
|
||||
List<TpkCommonString.Entry> commonStrings = [];
|
||||
Dictionary<int, string> latestUnityClassesDumped = [];
|
||||
Dictionary<int, TpkClassInformation> classDictionary = [];
|
||||
|
||||
foreach (UnityInfo info in infosOrderedByUnityVersion)
|
||||
foreach ((UnityVersion version, UnityInfo? info) in infosOrderedByUnityVersion)
|
||||
{
|
||||
Console.WriteLine(info.Version);
|
||||
UnityVersion version = UnityVersion.Parse(info.Version);
|
||||
Console.WriteLine(version.ToString());
|
||||
blob.Versions.Add(version);
|
||||
|
||||
if (info.Strings.Count != latestCommonStringCount)
|
||||
if (!Same(info.Strings, commonStrings, blob.StringBuffer))
|
||||
{
|
||||
latestCommonStringCount = (byte)info.Strings.Count;
|
||||
blob.CommonString.Add(version, latestCommonStringCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < info.Strings.Count; i++)
|
||||
{
|
||||
if (i < commonStrings.Count)
|
||||
commonStrings.Clear();
|
||||
commonStrings.EnsureCapacity(commonStrings.Count);
|
||||
foreach (UnityString unityString in info.Strings)
|
||||
{
|
||||
if (info.Strings[i].String != commonStrings[i])
|
||||
{
|
||||
throw new Exception($"String inequality at index {i} for version {version}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
commonStrings.Add(info.Strings[i].String);
|
||||
commonStrings.Add(new TpkCommonString.Entry((ushort)unityString.Index, unityString.String, blob.StringBuffer));
|
||||
}
|
||||
blob.CommonString.Add(version, commonStrings.ToArray());
|
||||
}
|
||||
|
||||
foreach (UnityClass unityClass in info.Classes)
|
||||
@@ -115,8 +109,7 @@ namespace AssetRipper.Tpk.ConsoleApp
|
||||
|
||||
blob.ClassInformation.AddRange(classDictionary.Values);
|
||||
|
||||
blob.CommonString.SetIndices(blob.StringBuffer, commonStrings);
|
||||
//About 21k / 65k
|
||||
//About 26k / 65k
|
||||
Console.WriteLine($"Node buffer has {blob.NodeBuffer.Count} entries, which is {GetUShortPercent(blob.NodeBuffer.Count)}% of its maximum {ushort.MaxValue} entries");
|
||||
//About 7k / 65k
|
||||
Console.WriteLine($"String buffer has {blob.StringBuffer.Count} entries, which is {GetUShortPercent(blob.StringBuffer.Count)}% of its maximum {ushort.MaxValue} entries");
|
||||
@@ -126,6 +119,22 @@ namespace AssetRipper.Tpk.ConsoleApp
|
||||
return blob;
|
||||
}
|
||||
|
||||
private static bool Same(List<UnityString> jsonStrings, List<TpkCommonString.Entry> tpkEntries, TpkStringBuffer stringBuffer)
|
||||
{
|
||||
if (jsonStrings.Count != tpkEntries.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < jsonStrings.Count; i++)
|
||||
{
|
||||
if (jsonStrings[i].String != tpkEntries[i].ToString(stringBuffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int GetUShortPercent(int value) => value * 100 / ushort.MaxValue;
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,9 @@ namespace AssetRipper.Tpk.ConsoleApp
|
||||
/// </summary>
|
||||
/// <param name="zipFilePath"></param>
|
||||
/// <returns>A list ordered by Unity version</returns>
|
||||
public static IEnumerable<UnityInfo> ReadUnityInfoFromZipFile(string zipFilePath)
|
||||
public static IEnumerable<(UnityVersion Version, UnityInfo Info)> ReadUnityInfoFromZipFile(string zipFilePath)
|
||||
{
|
||||
List<UnityInfo> list = new();
|
||||
List<(UnityVersion Version, UnityInfo Info)> list = new();
|
||||
|
||||
using FileStream fileStream = File.OpenRead(zipFilePath);
|
||||
using IWritableArchive<ZipWriterOptions> archive = ZipArchive.OpenArchive(fileStream);
|
||||
@@ -24,37 +24,22 @@ namespace AssetRipper.Tpk.ConsoleApp
|
||||
{
|
||||
if (!entry.IsDirectory && (entry.Key ?? "").EndsWith(".json", StringComparison.Ordinal))
|
||||
{
|
||||
string versionString = Path.GetFileNameWithoutExtension(entry.Key ?? "");
|
||||
UnityVersion version = UnityVersion.Parse(versionString);
|
||||
using MemoryStream unzippedFileStream = new MemoryStream();
|
||||
entry.WriteTo(unzippedFileStream);
|
||||
unzippedFileStream.Position = 0;
|
||||
UnityInfo? info = UnityInfo.FromStream(unzippedFileStream);
|
||||
if (info is not null)
|
||||
{
|
||||
list.Add(info);
|
||||
list.Add((version, info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.Sort(CompareUnityInfo);
|
||||
list.Sort((a, b) => a.Version.CompareTo(b.Version));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two UnityInfo by their versions
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>
|
||||
/// Less than zero: a precedes b<br />
|
||||
/// Zero: equivalent position<br />
|
||||
/// Greater than zero: a follows b
|
||||
/// </returns>
|
||||
private static int CompareUnityInfo(UnityInfo a, UnityInfo b)
|
||||
{
|
||||
UnityVersion versionA = UnityVersion.Parse(a.Version);
|
||||
UnityVersion versionB = UnityVersion.Parse(b.Version);
|
||||
return versionA.CompareTo(versionB);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,12 @@ public class EngineAssetsTests
|
||||
originalBlob.Data.Add(new KeyValuePair<UnityVersion, string>(new UnityVersion(4), RandomUtils.RandomString()));
|
||||
byte[] writtenData = originalBlob.ToBinary();
|
||||
TpkEngineAssetsBlob readBlob = TpkDataBlob.FromBinary<TpkEngineAssetsBlob>(writtenData);
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(readBlob.CreationTime, Is.EqualTo(originalBlob.CreationTime));
|
||||
Assert.That(readBlob.Versions, Is.EqualTo(originalBlob.Versions));
|
||||
Assert.That(readBlob.Data, Is.EqualTo(originalBlob.Data));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -33,11 +33,11 @@ public class EngineAssetsTests
|
||||
TpkEngineAssetsBlob originalBlob = new();
|
||||
byte[] writtenData = originalBlob.ToBinary();
|
||||
TpkEngineAssetsBlob readBlob = TpkDataBlob.FromBinary<TpkEngineAssetsBlob>(writtenData);
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(readBlob.CreationTime, Is.EqualTo(originalBlob.CreationTime));
|
||||
Assert.That(readBlob.Versions, Is.EqualTo(originalBlob.Versions));
|
||||
Assert.That(readBlob.Data, Is.EqualTo(originalBlob.Data));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>AssetRipper.Tpk.Tests</RootNamespace>
|
||||
@@ -7,14 +7,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
|
||||
<PackageReference Include="NUnit" Version="4.5.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.12.0">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
|
||||
<PackageReference Include="NUnit" Version="4.6.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.14.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="8.0.1">
|
||||
<PackageReference Include="coverlet.collector" Version="10.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -9,13 +9,13 @@ namespace AssetRipper.Tpk.Tests
|
||||
{
|
||||
TpkFile file = CreateTpkFile();
|
||||
byte[] data = file.WriteToMemory();
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(data[0], Is.EqualTo((byte)'T'));
|
||||
Assert.That(data[1], Is.EqualTo((byte)'P'));
|
||||
Assert.That(data[2], Is.EqualTo((byte)'K'));
|
||||
Assert.That(data[3], Is.EqualTo((byte)'*'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static TpkFile CreateTpkFile()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using AssetRipper.Primitives;
|
||||
using AssetRipper.Tpk.TypeTrees;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetRipper.Tpk.Tests.TypeTrees
|
||||
{
|
||||
@@ -9,35 +10,54 @@ namespace AssetRipper.Tpk.Tests.TypeTrees
|
||||
private static UnityVersion Unity3 => new UnityVersion(3, 0, 0, UnityVersionType.Final, 1);
|
||||
private static UnityVersion Unity4 => new UnityVersion(4, 0, 0, UnityVersionType.Final, 1);
|
||||
private static UnityVersion Unity5 => new UnityVersion(5, 0, 0, UnityVersionType.Final, 1);
|
||||
private static UnityVersion Unity6 => new UnityVersion(6, 0, 0, UnityVersionType.Final, 1);
|
||||
private static UnityVersion Unity7 => new UnityVersion(7, 0, 0, UnityVersionType.Final, 1);
|
||||
private static UnityVersion Unity6 => new UnityVersion(6000, 0, 0, UnityVersionType.Final, 1);
|
||||
private static UnityVersion Unity7 => new UnityVersion(7000, 0, 0, UnityVersionType.Final, 1);
|
||||
|
||||
[Test]
|
||||
public static void CountIsCorrectForEmptyCommonString()
|
||||
{
|
||||
TpkCommonString commonString = new();
|
||||
Assert.That(commonString.GetCount(Unity5), Is.EqualTo(0));
|
||||
Assert.That(commonString.GetEntries(Unity5), Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void CountIsCorrectForNormalUse()
|
||||
{
|
||||
TpkCommonString commonString = MakeCommonString();
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(commonString.GetCount(Unity3), Is.EqualTo(5));
|
||||
Assert.That(commonString.GetCount(Unity4), Is.EqualTo(5));
|
||||
Assert.That(commonString.GetCount(Unity5), Is.EqualTo(5));
|
||||
Assert.That(commonString.GetCount(Unity6), Is.EqualTo(10));
|
||||
Assert.That(commonString.GetCount(Unity7), Is.EqualTo(10));
|
||||
});
|
||||
Assert.That(commonString.GetEntries(Unity3), Has.Length.EqualTo(5));
|
||||
Assert.That(commonString.GetEntries(Unity4), Has.Length.EqualTo(5));
|
||||
Assert.That(commonString.GetEntries(Unity5), Has.Length.EqualTo(5));
|
||||
Assert.That(commonString.GetEntries(Unity6), Has.Length.EqualTo(10));
|
||||
Assert.That(commonString.GetEntries(Unity7), Has.Length.EqualTo(10));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void ReadingAndWritingUseSameBytes()
|
||||
{
|
||||
TpkCommonString commonString = MakeCommonString();
|
||||
MemoryStream stream = new();
|
||||
BinaryWriter writer = new(stream);
|
||||
commonString.Write(writer);
|
||||
writer.Flush();
|
||||
int bytesWritten = (int)stream.Length;
|
||||
|
||||
stream.Position = 0;
|
||||
BinaryReader reader = new(stream);
|
||||
TpkCommonString readCommonString = new();
|
||||
readCommonString.Read(reader);
|
||||
int bytesRead = (int)stream.Position;
|
||||
|
||||
Assert.That(bytesRead, Is.EqualTo(bytesWritten));
|
||||
}
|
||||
|
||||
private static TpkCommonString MakeCommonString()
|
||||
{
|
||||
TpkCommonString commonString = new();
|
||||
commonString.Add(Unity4, 5);
|
||||
commonString.Add(Unity6, 10);
|
||||
commonString.Add(Unity4, new TpkCommonString.Entry[5]);
|
||||
commonString.Add(Unity6, new TpkCommonString.Entry[10]);
|
||||
return commonString;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
|
||||
<PackageReference Include="NUnit" Version="4.5.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.12.0">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
|
||||
<PackageReference Include="NUnit" Version="4.6.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.14.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="8.0.1">
|
||||
<PackageReference Include="coverlet.collector" Version="10.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -30,8 +30,6 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
result.Module = "";
|
||||
//TypeID gets set elsewhere
|
||||
result.Base = stringBuffer[source.Base];
|
||||
result.Size = -1;
|
||||
//Type index is ignored
|
||||
result.IsAbstract = source.Flags.IsAbstract();
|
||||
result.IsSealed = source.Flags.IsSealed();
|
||||
result.IsEditorOnly = source.Flags.IsEditorOnly();
|
||||
@@ -39,11 +37,11 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
result.IsStripped = source.Flags.IsStripped();
|
||||
if (source.EditorRootNode != ushort.MaxValue)
|
||||
{
|
||||
result.EditorRootNode = NodeConversion.Convert(nodeBuffer[source.EditorRootNode], stringBuffer, nodeBuffer, 0, 0, out var _);
|
||||
result.EditorRootNode = NodeConversion.Convert(nodeBuffer[source.EditorRootNode], stringBuffer, nodeBuffer);
|
||||
}
|
||||
if (source.ReleaseRootNode != ushort.MaxValue)
|
||||
{
|
||||
result.ReleaseRootNode = NodeConversion.Convert(nodeBuffer[source.ReleaseRootNode], stringBuffer, nodeBuffer, 0, 0, out var _);
|
||||
result.ReleaseRootNode = NodeConversion.Convert(nodeBuffer[source.ReleaseRootNode], stringBuffer, nodeBuffer);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -24,26 +24,23 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
return nodeBuffer.AddNode(nodeData);
|
||||
}
|
||||
|
||||
public static UnityNode Convert(TpkUnityNode nodeData, TpkStringBuffer stringBuffer, TpkUnityNodeBuffer nodeBuffer, byte level, int index, out int lastIndexUsed)
|
||||
public static UnityNode Convert(TpkUnityNode nodeData, TpkStringBuffer stringBuffer, TpkUnityNodeBuffer nodeBuffer)
|
||||
{
|
||||
UnityNode result = new UnityNode();
|
||||
result.TypeName = stringBuffer[nodeData.TypeName];
|
||||
result.Name = stringBuffer[nodeData.Name];
|
||||
result.Level = level;
|
||||
result.ByteSize = nodeData.ByteSize;
|
||||
result.Index = index;
|
||||
result.Version = nodeData.Version;
|
||||
result.TypeFlags = nodeData.TypeFlags;
|
||||
result.MetaFlag = nodeData.MetaFlag;
|
||||
UnityNode result = new()
|
||||
{
|
||||
TypeName = stringBuffer[nodeData.TypeName],
|
||||
Name = stringBuffer[nodeData.Name],
|
||||
ByteSize = nodeData.ByteSize,
|
||||
Version = nodeData.Version,
|
||||
TypeFlags = nodeData.TypeFlags,
|
||||
MetaFlag = nodeData.MetaFlag,
|
||||
};
|
||||
|
||||
byte levelPlus = unchecked((byte)(level + 1U));
|
||||
lastIndexUsed = index;
|
||||
int subNodeCount = nodeData.SubNodes.Length;
|
||||
result.SubNodes = new List<UnityNode>(subNodeCount);
|
||||
for (int i = 0; i < subNodeCount; i++)
|
||||
{
|
||||
result.SubNodes.Add(Convert(nodeBuffer[nodeData.SubNodes[i]], stringBuffer, nodeBuffer, levelPlus, index + 1, out lastIndexUsed));
|
||||
index = lastIndexUsed;
|
||||
result.SubNodes.Add(Convert(nodeBuffer[nodeData.SubNodes[i]], stringBuffer, nodeBuffer));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AssetRipper.HashAlgorithms" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.201">
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.300">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
using System.Text.Json;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
public sealed class UnityClass
|
||||
{
|
||||
private string name = "";
|
||||
private string @namespace = "";
|
||||
private string fullName = "";
|
||||
private string module = "";
|
||||
private string @base = "";
|
||||
private List<string> derived = new();
|
||||
|
||||
/// <summary>
|
||||
/// The name of the class not including the namespace
|
||||
/// </summary>
|
||||
public string Name { get => name; set => name = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string Name { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The namespace of the class if it exists
|
||||
/// </summary>
|
||||
public string Namespace { get => @namespace; set => @namespace = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string Namespace { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The full name of the class including the namespace but not an assembly specification
|
||||
/// </summary>
|
||||
public string FullName { get => fullName; set => fullName = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string FullName { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The module containing the class
|
||||
/// </summary>
|
||||
public string Module { get => module; set => module = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string Module { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The unique number used to identify the class
|
||||
/// </summary>
|
||||
@@ -35,11 +33,13 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
/// <summary>
|
||||
/// The name of the base class if it exists. Namespace not included
|
||||
/// </summary>
|
||||
public string Base { get => @base; set => @base = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string Base { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The names of the classes that directly derive from this. Namespaces not included
|
||||
/// </summary>
|
||||
public List<string> Derived { get => derived; set => derived = value ?? new(); }
|
||||
[AllowNull]
|
||||
public List<string> Derived { get; set => field = value ?? []; } = [];
|
||||
/// <summary>
|
||||
/// The count of all classes that descend from this class<br/>
|
||||
/// It includes this class, so the count is always positive<br/>
|
||||
@@ -47,14 +47,6 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
/// </summary>
|
||||
public uint DescendantCount { get; set; }
|
||||
/// <summary>
|
||||
/// The size in bytes of one object. Doesn't include alignments. May be wildly inaccurate, especially for classes with variable size.
|
||||
/// </summary>
|
||||
public int Size { get; set; }
|
||||
/// <summary>
|
||||
/// The zero based index of this class in the list of acquired classes. Doesn't mean much.
|
||||
/// </summary>
|
||||
public uint TypeIndex { get; set; }
|
||||
/// <summary>
|
||||
/// Is the class abstract?
|
||||
/// </summary>
|
||||
public bool IsAbstract { get; set; }
|
||||
@@ -81,7 +73,9 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
/// <summary>
|
||||
/// The constructor used in json deserialization
|
||||
/// </summary>
|
||||
public UnityClass() { }
|
||||
public UnityClass()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor used to make dependent class definitions
|
||||
@@ -100,7 +94,6 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
TypeID = -1;
|
||||
Derived = new List<string>();
|
||||
DescendantCount = 1;
|
||||
Size = mainRootNode.ByteSize;
|
||||
IsAbstract = false;
|
||||
IsSealed = true;
|
||||
IsEditorOnly = releaseRootNode == null;
|
||||
@@ -153,13 +146,13 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
public string ToJsonString(bool indented = false)
|
||||
{
|
||||
return indented
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContextIndented.Default.UnityClass)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContextNotIndented.Default.UnityClass);
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteIndentedContext.UnityClass)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteNotIndentedContext.UnityClass);
|
||||
}
|
||||
|
||||
public static UnityClass? FromJsonString(string jsonString)
|
||||
{
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContextIndented.Default.UnityClass);
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContext.Default.UnityClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,23 @@
|
||||
using System.Text.Json;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
public sealed class UnityInfo
|
||||
{
|
||||
private string version = "";
|
||||
private List<UnityString> strings = new();
|
||||
private List<UnityClass> classes = new();
|
||||
|
||||
public string Version
|
||||
{
|
||||
get => version;
|
||||
set => version = value ?? "";
|
||||
}
|
||||
|
||||
[AllowNull]
|
||||
public List<UnityString> Strings
|
||||
{
|
||||
get => strings;
|
||||
set => strings = value ?? new();
|
||||
}
|
||||
get;
|
||||
set => field = value ?? new();
|
||||
} = new();
|
||||
|
||||
[AllowNull]
|
||||
public List<UnityClass> Classes
|
||||
{
|
||||
get => classes;
|
||||
set => classes = value ?? new();
|
||||
}
|
||||
get;
|
||||
set => field = value ?? new();
|
||||
} = new();
|
||||
|
||||
public static UnityInfo ReadFromJsonFile(string jsonPath)
|
||||
{
|
||||
@@ -35,18 +28,18 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
public string ToJsonString(bool indented = false)
|
||||
{
|
||||
return indented
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContextIndented.Default.UnityInfo)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContextNotIndented.Default.UnityInfo);
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteIndentedContext.UnityInfo)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteNotIndentedContext.UnityInfo);
|
||||
}
|
||||
|
||||
public static UnityInfo? FromJsonString(string jsonString)
|
||||
{
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContextIndented.Default.UnityInfo);
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContext.Default.UnityInfo);
|
||||
}
|
||||
|
||||
public static UnityInfo? FromStream(Stream utf8JsonStream)
|
||||
{
|
||||
return JsonSerializer.Deserialize(utf8JsonStream, UnityInfoSerializerContextIndented.Default.UnityInfo);
|
||||
return JsonSerializer.Deserialize(utf8JsonStream, UnityInfoSerializerContext.Default.UnityInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
[JsonSourceGenerationOptions(IndentCharacter = '\t', IndentSize = 1)]
|
||||
[JsonSerializable(typeof(UnityInfo))]
|
||||
internal sealed partial class UnityInfoSerializerContext : JsonSerializerContext
|
||||
{
|
||||
public static UnityInfoSerializerContext WriteIndentedContext { get; }
|
||||
public static UnityInfoSerializerContext WriteNotIndentedContext { get; }
|
||||
|
||||
static UnityInfoSerializerContext()
|
||||
{
|
||||
JsonSerializerOptions WriteIndentedOptions = new(s_defaultOptions)
|
||||
{
|
||||
WriteIndented = true,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
WriteIndentedContext = new UnityInfoSerializerContext(WriteIndentedOptions);
|
||||
|
||||
JsonSerializerOptions WriteNotIndentedOptions = new(s_defaultOptions)
|
||||
{
|
||||
WriteIndented = false,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
WriteNotIndentedContext = new UnityInfoSerializerContext(WriteNotIndentedOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(UnityInfo))]
|
||||
internal sealed partial class UnityInfoSerializerContextIndented : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
[JsonSourceGenerationOptions(WriteIndented = false)]
|
||||
[JsonSerializable(typeof(UnityInfo))]
|
||||
internal sealed partial class UnityInfoSerializerContextNotIndented : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using AssetRipper.HashAlgorithms;
|
||||
using System.Buffers;
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -9,39 +10,39 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
public sealed class UnityNode
|
||||
{
|
||||
public string TypeName { get => typeName; set => typeName = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string TypeName { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The original type name as obtained from the json file
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[AllowNull]
|
||||
public string OriginalTypeName
|
||||
{
|
||||
get => string.IsNullOrEmpty(originalTypeName) ? TypeName : originalTypeName;
|
||||
set => originalTypeName = value ?? "";
|
||||
}
|
||||
public string Name { get => name; set => name = value ?? ""; }
|
||||
[AllowNull]
|
||||
public string Name { get; set => field = value ?? ""; } = "";
|
||||
/// <summary>
|
||||
/// The original name as obtained from the json file
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[AllowNull]
|
||||
public string OriginalName
|
||||
{
|
||||
get => string.IsNullOrEmpty(originalName) ? Name : originalName;
|
||||
set => originalName = value ?? "";
|
||||
}
|
||||
public byte Level { get; set; }
|
||||
public int ByteSize { get; set; }
|
||||
public int Index { get; set; }
|
||||
public short Version { get; set; }
|
||||
public byte TypeFlags { get; set; }
|
||||
public uint MetaFlag { get; set; }
|
||||
public List<UnityNode> SubNodes { get => subNodes; set => subNodes = value ?? new(); }
|
||||
[AllowNull]
|
||||
public List<UnityNode> SubNodes { get; set => field = value ?? []; } = [];
|
||||
|
||||
private string originalTypeName = "";
|
||||
private string originalName = "";
|
||||
private string typeName = "";
|
||||
private string name = "";
|
||||
private List<UnityNode> subNodes = new();
|
||||
|
||||
/// <summary>
|
||||
/// Deep clones a node and all its subnodes<br/>
|
||||
@@ -50,36 +51,30 @@ namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
/// <returns>The new node</returns>
|
||||
public UnityNode DeepClone()
|
||||
{
|
||||
UnityNode cloned = new UnityNode();
|
||||
cloned.TypeName = CloneString(TypeName);
|
||||
cloned.originalTypeName = CloneString(originalTypeName);
|
||||
cloned.Name = CloneString(Name);
|
||||
cloned.originalName = CloneString(originalName);
|
||||
cloned.Level = Level;
|
||||
cloned.ByteSize = ByteSize;
|
||||
cloned.Index = Index;
|
||||
cloned.Version = Version;
|
||||
cloned.TypeFlags = TypeFlags;
|
||||
cloned.MetaFlag = MetaFlag;
|
||||
cloned.SubNodes = SubNodes.ConvertAll(x => x.DeepClone());
|
||||
return cloned;
|
||||
}
|
||||
|
||||
private static string CloneString(string? @string)
|
||||
{
|
||||
return @string == null ? "" : new string(@string);
|
||||
return new UnityNode
|
||||
{
|
||||
TypeName = TypeName,
|
||||
originalTypeName = originalTypeName,
|
||||
Name = Name,
|
||||
originalName = originalName,
|
||||
ByteSize = ByteSize,
|
||||
Version = Version,
|
||||
TypeFlags = TypeFlags,
|
||||
MetaFlag = MetaFlag,
|
||||
SubNodes = SubNodes.ConvertAll(x => x.DeepClone()),
|
||||
};
|
||||
}
|
||||
|
||||
public string ToJsonString(bool indented = false)
|
||||
{
|
||||
return indented
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContextIndented.Default.UnityNode)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContextNotIndented.Default.UnityNode);
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteIndentedContext.UnityNode)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteNotIndentedContext.UnityNode);
|
||||
}
|
||||
|
||||
public static UnityNode? FromJsonString(string jsonString)
|
||||
{
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContextIndented.Default.UnityNode);
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContext.Default.UnityNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
using System.Text.Json;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AssetRipper.Tpk.TypeTrees.Json
|
||||
{
|
||||
public sealed class UnityString
|
||||
public sealed record class UnityString
|
||||
{
|
||||
private string @string = "";
|
||||
|
||||
public uint Index { get; set; }
|
||||
public string String { get => @string; set => @string = value ?? ""; }
|
||||
|
||||
[AllowNull]
|
||||
public string String { get; set => field = value ?? ""; } = "";
|
||||
|
||||
public string ToJsonString(bool indented = false)
|
||||
{
|
||||
return indented
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContextIndented.Default.UnityString)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContextNotIndented.Default.UnityString);
|
||||
? JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteIndentedContext.UnityString)
|
||||
: JsonSerializer.Serialize(this, UnityInfoSerializerContext.WriteNotIndentedContext.UnityString);
|
||||
}
|
||||
|
||||
public static UnityString? FromJsonString(string jsonString)
|
||||
{
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContextIndented.Default.UnityString);
|
||||
return JsonSerializer.Deserialize(jsonString, UnityInfoSerializerContext.Default.UnityString);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -17,11 +17,11 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AssetRipper.Primitives" Version="3.2.0" />
|
||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.201">
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.300">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SharpCompress" Version="0.47.3" />
|
||||
<PackageReference Include="SharpCompress" Version="0.49.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -8,7 +8,7 @@
|
||||
/// <summary>
|
||||
/// Name : Blob
|
||||
/// </summary>
|
||||
public List<KeyValuePair<string, TpkDataBlob>> Blobs { get; } = new List<KeyValuePair<string, TpkDataBlob>>();
|
||||
public List<KeyValuePair<string, TpkDataBlob>> Blobs { get; } = [];
|
||||
|
||||
public override TpkDataType DataType => TpkDataType.Collection;
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ namespace AssetRipper.Tpk
|
||||
public sealed class TpkFile
|
||||
{
|
||||
public const uint TpkMagicBytes = 0x2A4B5054; // TPK* in binary
|
||||
public const byte TpkVersionNumber = 1;
|
||||
public const byte TpkVersionNumber = 2;
|
||||
|
||||
public TpkCompressionType CompressionType { get; private set; }
|
||||
public TpkDataType DataType { get; private set; }
|
||||
|
||||
@@ -21,7 +21,9 @@ namespace AssetRipper.Tpk.TypeTrees
|
||||
/// </summary>
|
||||
public List<VersionClassPair> Classes { get; } = new();
|
||||
|
||||
public TpkClassInformation() { }
|
||||
public TpkClassInformation()
|
||||
{
|
||||
}
|
||||
|
||||
public TpkClassInformation(int id)
|
||||
{
|
||||
|
||||
@@ -9,33 +9,51 @@ namespace AssetRipper.Tpk.TypeTrees
|
||||
public sealed class TpkCommonString
|
||||
{
|
||||
/// <summary>
|
||||
/// Unity version : string count<br/>
|
||||
/// Sequential by ascending Unity version
|
||||
/// An entry in <see cref="TpkCommonString"/>
|
||||
/// </summary>
|
||||
public List<KeyValuePair<UnityVersion, byte>> VersionInformation { get; } = new();
|
||||
public List<ushort> StringBufferIndices { get; } = new();
|
||||
|
||||
public void Add(UnityVersion version, byte count)
|
||||
/// <param name="Offset">The byte offset of the string</param>
|
||||
/// <param name="String">The index of the string in <see cref="TpkStringBuffer"/></param>
|
||||
public readonly record struct Entry(ushort Offset, ushort String)
|
||||
{
|
||||
VersionInformation.Add(new KeyValuePair<UnityVersion, byte>(version, count));
|
||||
}
|
||||
|
||||
public void SetIndices(TpkStringBuffer buffer, List<string> strings)
|
||||
{
|
||||
int count = strings.Count;
|
||||
StringBufferIndices.Clear();
|
||||
StringBufferIndices.Capacity = count;
|
||||
for (int i = 0; i < count; i++)
|
||||
public Entry(ushort offset, string @string, TpkStringBuffer buffer) : this(offset, buffer.AddString(@string))
|
||||
{
|
||||
StringBufferIndices.Add(buffer.AddString(strings[i]));
|
||||
}
|
||||
|
||||
public string ToString(TpkStringBuffer buffer)
|
||||
{
|
||||
return buffer[String];
|
||||
}
|
||||
|
||||
public static Entry Read(BinaryReader reader)
|
||||
{
|
||||
ushort offset = reader.ReadUInt16();
|
||||
ushort stringIndex = reader.ReadUInt16();
|
||||
return new Entry(offset, stringIndex);
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(Offset);
|
||||
writer.Write(String);
|
||||
}
|
||||
}
|
||||
|
||||
public byte GetCount(UnityVersion exactVersion)
|
||||
/// <summary>
|
||||
/// Unity version : string count<br/>
|
||||
/// Sequential by ascending Unity version
|
||||
/// </summary>
|
||||
public List<KeyValuePair<UnityVersion, Entry[]>> VersionInformation { get; } = new();
|
||||
|
||||
public void Add(UnityVersion version, Entry[] entries)
|
||||
{
|
||||
VersionInformation.Add(new KeyValuePair<UnityVersion, Entry[]>(version, entries));
|
||||
}
|
||||
|
||||
public Entry[] GetEntries(UnityVersion exactVersion)
|
||||
{
|
||||
if (VersionInformation.Count == 0)
|
||||
{
|
||||
return 0;
|
||||
return [];
|
||||
}
|
||||
for (int i = 1; i < VersionInformation.Count; i++)
|
||||
{
|
||||
@@ -44,18 +62,7 @@ namespace AssetRipper.Tpk.TypeTrees
|
||||
return VersionInformation[i - 1].Value;
|
||||
}
|
||||
}
|
||||
return VersionInformation[VersionInformation.Count - 1].Value;
|
||||
}
|
||||
|
||||
public string[] GetStrings(TpkStringBuffer buffer)
|
||||
{
|
||||
int length = StringBufferIndices.Count;
|
||||
string[] strings = new string[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
strings[i] = buffer[StringBufferIndices[i]];
|
||||
}
|
||||
return strings;
|
||||
return VersionInformation[^1].Value;
|
||||
}
|
||||
|
||||
public void Read(BinaryReader reader)
|
||||
@@ -66,15 +73,13 @@ namespace AssetRipper.Tpk.TypeTrees
|
||||
for (int i = 0; i < versionCount; i++)
|
||||
{
|
||||
UnityVersion version = reader.ReadUnityVersion();
|
||||
byte stringCount = reader.ReadByte();
|
||||
VersionInformation.Add(new KeyValuePair<UnityVersion, byte>(version, stringCount));
|
||||
}
|
||||
int indicesCount = reader.ReadInt32();
|
||||
StringBufferIndices.Clear();
|
||||
StringBufferIndices.Capacity = indicesCount;
|
||||
for (int j = 0; j < indicesCount; j++)
|
||||
{
|
||||
StringBufferIndices.Add(reader.ReadUInt16());
|
||||
int entryCount = reader.ReadInt32();
|
||||
Entry[] entries = new Entry[entryCount];
|
||||
for (int j = 0; j < entryCount; j++)
|
||||
{
|
||||
entries[j] = Entry.Read(reader);
|
||||
}
|
||||
VersionInformation.Add(new KeyValuePair<UnityVersion, Entry[]>(version, entries));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,12 +89,12 @@ namespace AssetRipper.Tpk.TypeTrees
|
||||
for (int i = 0; i < VersionInformation.Count; i++)
|
||||
{
|
||||
writer.Write(VersionInformation[i].Key);
|
||||
writer.Write(VersionInformation[i].Value);
|
||||
}
|
||||
writer.Write(StringBufferIndices.Count);
|
||||
for (int i = 0; i < StringBufferIndices.Count; i++)
|
||||
{
|
||||
writer.Write(StringBufferIndices[i]);
|
||||
Entry[] entries = VersionInformation[i].Value;
|
||||
writer.Write(entries.Length);
|
||||
for (int j = 0; j < entries.Length; j++)
|
||||
{
|
||||
entries[j].Write(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
//Derived and Descendent count are excluded from this format
|
||||
|
||||
//Size and TypeIndex are excluded from this format
|
||||
|
||||
/// <summary>
|
||||
/// 8 boolean values packed into 1 byte
|
||||
/// </summary>
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
{
|
||||
public ushort TypeName { get; set; }
|
||||
public ushort Name { get; set; }
|
||||
//Level is redundant
|
||||
public int ByteSize { get; set; }
|
||||
//Index is redundant
|
||||
public short Version { get; set; }
|
||||
public byte TypeFlags { get; set; }
|
||||
public uint MetaFlag { get; set; }
|
||||
public ushort[] SubNodes { get; set; } = Array.Empty<ushort>();
|
||||
public ushort[] SubNodes { get; set; } = [];
|
||||
|
||||
public void Read(BinaryReader reader)
|
||||
{
|
||||
@@ -62,21 +60,7 @@
|
||||
Version == other.Version &&
|
||||
TypeFlags == other.TypeFlags &&
|
||||
MetaFlag == other.MetaFlag &&
|
||||
ArrayEqual(SubNodes, other.SubNodes);
|
||||
}
|
||||
|
||||
private static bool ArrayEqual(ushort[] array1, ushort[] array2)
|
||||
{
|
||||
if (array1.Length != array2.Length)
|
||||
return false;
|
||||
for (int i = 0; i < array1.Length; i++)
|
||||
{
|
||||
if (array1[i] != array2[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
SubNodes.SequenceEqual(other.SubNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user