12 Commits
Author SHA1 Message Date
ds5678 be9d53f317 Bump version to 1.2.1
This is the last version before 2.0
2026-07-01 21:31:02 -07:00
ds5678 a7e3d89b2d Ensure that json serialization uses minimal character escaping 2026-07-01 21:24:47 -07:00
ds5678 21eca606fd Remove Size and TypeIndex from UnityClass 2026-06-30 14:56:23 -07:00
ds5678 8bef636a8f Remove Level and Index from UnityNode 2026-06-30 14:42:48 -07:00
ds5678 7ed791b58c Remove Version from UnityInfo 2026-06-30 14:35:11 -07:00
ds5678 236236fed8 Merge indented and not indented json serializer contexts 2026-06-30 14:22:36 -07:00
ds5678 019d733bb2 Refactor to use newer coding conventions 2026-06-30 14:12:34 -07:00
ds5678 7663a53449 Replace Assert.Multiple with Assert.EnterMultipleScope
Updated test methods to use Assert.EnterMultipleScope instead of Assert.Multiple for grouping multiple assertions, reflecting the preferred NUnit API. This change affects EngineAssetsTests.cs, TpkFileTests.cs, and CommonStringTests.cs.
2026-06-30 13:08:23 -07:00
ds5678 f9e25d911f Update dependencies
- Updated SharpCompress to 0.49.1 in Tpk.csproj and removed from Tpk.ConsoleApp.csproj
- Bumped Microsoft.SourceLink.GitHub to 10.0.300 in Tpk and Tpk.TypeTrees.Json
- Updated test dependencies: Microsoft.NET.Test.Sdk, NUnit, NUnit.Analyzers, and coverlet.collector
2026-06-30 13:05:16 -07:00
dependabot[bot] a4f6013e45 Bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-06-26 19:34:18 -07:00
dependabot[bot] 1b0a2b3082 Bump NUnit.Analyzers from 4.12.0 to 4.13.0
---
updated-dependencies:
- dependency-name: NUnit.Analyzers
  dependency-version: 4.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: NUnit.Analyzers
  dependency-version: 4.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-17 21:41:34 -07:00
dependabot[bot] b5b5ace321 Bump SharpCompress from 0.47.3 to 0.47.4
---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-version: 0.47.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-24 23:26:52 -07:00
28 changed files with 163 additions and 205 deletions

No files matched your search

+2 -2
View File
@@ -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
+1 -1
View File
@@ -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:
+2 -2
View File
@@ -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'
+1 -1
View File
@@ -9,7 +9,7 @@
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<VersionPrefix>1.2.0</VersionPrefix>
<VersionPrefix>1.2.1</VersionPrefix>
<RepositoryUrl>https://github.com/AssetRipper/Tpk</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
-4
View File
@@ -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" />
+10 -5
View File
@@ -28,10 +28,16 @@ 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);
@@ -41,10 +47,9 @@ namespace AssetRipper.Tpk.ConsoleApp
Dictionary<int, string> latestUnityClassesDumped = new Dictionary<int, string>();
Dictionary<int, TpkClassInformation> classDictionary = new Dictionary<int, TpkClassInformation>();
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)
+6 -21
View File
@@ -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);
}
}
}
+4 -4
View File
@@ -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));
});
}
}
}
+5 -5
View File
@@ -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>
+2 -2
View File
@@ -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()
+5 -5
View File
@@ -9,28 +9,28 @@ 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.GetCount(Unity5), Is.Zero);
}
[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));
});
}
}
private static TpkCommonString MakeCommonString()
@@ -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>
+2 -4
View File
@@ -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;
}
+11 -14
View File
@@ -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;
+1 -1
View File
@@ -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>
+20 -27
View File
@@ -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);
}
}
}
+14 -21
View File
@@ -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
{
}
}
+24 -29
View File
@@ -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>
+9 -8
View File
@@ -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
View File
@@ -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>
+1 -1
View File
@@ -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;
+3 -1
View File
@@ -21,7 +21,9 @@ namespace AssetRipper.Tpk.TypeTrees
/// </summary>
public List<VersionClassPair> Classes { get; } = new();
public TpkClassInformation() { }
public TpkClassInformation()
{
}
public TpkClassInformation(int id)
{
+1 -1
View File
@@ -44,7 +44,7 @@ namespace AssetRipper.Tpk.TypeTrees
return VersionInformation[i - 1].Value;
}
}
return VersionInformation[VersionInformation.Count - 1].Value;
return VersionInformation[^1].Value;
}
public string[] GetStrings(TpkStringBuffer buffer)
-2
View File
@@ -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>
+2 -18
View File
@@ -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);
}
}
}