73 Commits
Author SHA1 Message Date
dependabot[bot] 94549d10ee Bump Microsoft.SourceLink.GitHub from 10.0.300 to 10.0.301
---
updated-dependencies:
- dependency-name: Microsoft.SourceLink.GitHub
  dependency-version: 10.0.301
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-24 21:10:09 -07:00
dependabot[bot] 1a2c247668 Bump actions/setup-dotnet from 5 to 6
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 5 to 6.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-21 14:09:59 -07:00
ds5678 f94757d204 Bump version to 2.0.0 2026-07-03 11:17:38 -07:00
ds5678 474fe30489 Revert "Do not archive CI artifacts"
This reverts commit 70c3b6ca93.
2026-07-01 23:56:45 -07:00
ds5678 70c3b6ca93 Do not archive CI artifacts 2026-07-01 23:19:46 -07:00
ds5678 6b72bf855d Update binary format to support Unity 6.6 common string 2026-07-01 22:47:10 -07:00
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
ds5678 b899a92602 Bump version to 1.2.0
Updated the VersionPrefix in Directory.Build.props from 1.1.0 to 1.2.0 to prepare for a new project release. No other changes were made.
2026-03-30 13:50:46 -07:00
ds5678 c07faa29d5 [skip ci] Update Xml documentation 2026-03-30 13:49:58 -07:00
ds5678 066c28f93e Replace SharpZipLib with SharpCompress for ZIP handling
Switched from SharpZipLib to SharpCompress for reading ZIP files.
Updated project dependencies and refactored ZipFileReader.cs to use
SharpCompress APIs for extracting and processing JSON files from ZIP
archives. Existing JSON deserialization logic remains unchanged.
2026-03-30 13:41:02 -07:00
ds5678 a9014885b5 Formatting 2026-03-30 13:30:37 -07:00
Jeremy Pritts 1e52aabbba Delete .gitattributes 2026-03-30 13:25:20 -07:00
ds5678 5fa4cb3aec Fix CI 2026-03-30 13:23:08 -07:00
ds5678 742bfd10c7 Update to .NET 10.0 in project and CI workflows
Updated target framework to net10.0 in Directory.Build.props and changed setup-dotnet steps in GitHub Actions workflows to use dotnet-version 10.0.x. This ensures both local builds and CI pipelines use .NET 10.0.
2026-03-30 13:21:24 -07:00
ds5678 85a195481f Centralize project properties in Directory.Build.props
Move shared project settings to Directory.Build.props, including TargetFramework (net10.0), language version, nullability, and metadata. Remove redundant properties from individual .csproj files and add the new props file to the solution. This improves consistency and maintainability across all projects.
2026-03-30 13:20:05 -07:00
dependabot[bot] 0848676272 Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

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

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-30 13:09:15 -07:00
ds5678 ef5f006d86 Migrate solution from .sln to XML-based .slnx format
Replaced the traditional Visual Studio .sln file with a new XML-based Tpk.slnx solution file. The new format preserves the previous solution structure, including solution items, workflows, and project references. This migration aims to improve tooling compatibility and maintainability.
2026-03-30 13:08:58 -07:00
ds5678 63ae06b81c Update dependencies and migrate to LzmaStream.Create API
- Bump test dependencies (NUnit, Test SDK, adapters, coverlet)
- Update Microsoft.SourceLink.GitHub and SharpCompress versions
- Refactor LzmaHandler to use LzmaStream.Create factory methods
2026-03-30 13:07:35 -07:00
dependabot[bot] 0346ab5638 Bump coverlet.collector from 6.0.4 to 8.0.0 (#126)
---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: coverlet.collector
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-25 23:25:14 -08:00
dependabot[bot] 7b0d976098 Bump SharpCompress from 0.39.0 to 0.44.1 (#119)
---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-version: 0.44.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-20 14:57:43 -08:00
dependabot[bot] 78795b0f3b Bump Microsoft.NET.Test.Sdk from 17.13.0 to 18.0.1 (#109)
---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-19 12:41:49 -08:00
dependabot[bot] 631e16635c Bump NUnit.Analyzers from 4.7.0 to 4.11.2 (#111)
---
updated-dependencies:
- dependency-name: NUnit.Analyzers
  dependency-version: 4.11.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: NUnit.Analyzers
  dependency-version: 4.11.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-19 12:41:21 -08:00
dependabot[bot] 7c12284938 Bump NUnit3TestAdapter from 5.0.0 to 6.0.0 (#112)
---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: NUnit3TestAdapter
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-19 12:40:52 -08:00
Jeremy Pritts 3a92e1500d Update README 2025-12-18 11:57:47 -08:00
dependabot[bot] da9deb5c43 Bump actions/upload-artifact from 5 to 6 (#108)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 11:41:21 -08:00
dependabot[bot] 03866b2bd6 Bump actions/checkout from 5 to 6 (#107)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [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/v5...v6)

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

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-27 16:51:57 -08:00
Luke d3d2280b17 Use sparse checkouts to fix disk space issue (#106)
* Use sparse checkout when cloning TypeTreeDumps repo

this is done so the runner does not run out of disk space since the other folders can get quite large.

* hardcode typetreedumps ref to check if sparse checkouts fix the issue

* Revert ref testing commit
2025-11-05 22:08:36 -08:00
dependabot[bot] 43c367d0aa Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-11-01 01:12:13 -07:00
dependabot[bot] 04979752a5 Bump coverlet.collector from 6.0.2 to 6.0.4
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 6.0.2 to 6.0.4.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.2...v6.0.4)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-26 13:53:04 -07:00
dependabot[bot] 5954d55e23 Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [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/v4...v5)

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

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-12 14:07:50 -07:00
dependabot[bot] 2eaaef50da Bump actions/setup-dotnet from 4 to 5
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4 to 5.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-09-15 12:07:39 -07:00
dependabot[bot] 488e212e16 Bump SharpCompress from 0.38.0 to 0.39.0
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.38.0 to 0.39.0.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.38.0...0.39.0)

---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-08-06 20:27:10 -07:00
dependabot[bot] 24da9dda10 Bump NUnit3TestAdapter from 4.6.0 to 5.0.0
Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.6.0 to 5.0.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.6.0...V5.0.0)

---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-07-22 21:16:20 -07:00
dependabot[bot] 46e3867d3c Bump NUnit.Analyzers from 4.6.0 to 4.7.0
Bumps [NUnit.Analyzers](https://github.com/nunit/nunit.analyzers) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/nunit/nunit.analyzers/releases)
- [Changelog](https://github.com/nunit/nunit.analyzers/blob/master/CHANGES.md)
- [Commits](https://github.com/nunit/nunit.analyzers/compare/4.6.0...4.7.0)

---
updated-dependencies:
- dependency-name: NUnit.Analyzers
  dependency-version: 4.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-06-01 22:24:51 -07:00
dependabot[bot] 6bdc11a7cb Bump Microsoft.NET.Test.Sdk from 17.11.1 to 17.13.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.11.1 to 17.13.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.11.1...v17.13.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-05-06 20:59:51 -07:00
dependabot[bot] e7c20cfdd1 Bump AssetRipper.Primitives from 3.1.3 to 3.2.0
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 3.1.3 to 3.2.0.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/3.1.3...3.2.0)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-05-03 17:11:44 -07:00
ds5678 7eef5f06d1 Update to .NET 9.0 in YAML workflows
This commit updates the paths for the `AssetRipper.Tpk.ConsoleApp` executable in `engine_assets_tpk.yml` and `type_tree_tpk.yml`. References to the .NET 6.0 version have been replaced with the .NET 9.0 version. The changes include making the new executable executable and running it with the appropriate arguments for generating TPK files from engine assets and type tree dumps, ensuring the latest version is utilized in the workflows.
2025-03-01 17:58:43 -08:00
ds5678 8c6d9c46be Update .NET version to 9.0.x in workflows
Upgraded the .NET version from 6.0.x to 9.0.x in the
GitHub Actions workflows across `engine_assets_tpk.yml`,
`test.yml`, and `type_tree_tpk.yml` for improved build
process compatibility.
2025-03-01 17:56:31 -08:00
ds5678 1636b8a896 Update target framework to .NET 9.0 and version bump
- Changed target framework from .NET 6.0 to .NET 9.0 in
  `Tpk.ConsoleApp.csproj`, `Tpk.Tests.csproj`,
  `Tpk.TypeTrees.Json.Tests.csproj`, `Tpk.TypeTrees.Json.csproj`,
  and `Tpk.csproj`.

- Incremented version number from `1.0.1` to `1.1.0` for
  `Tpk.TypeTrees.Json` and `Tpk` projects.

- Updated copyright year from `2024` to `2025` in
  `Tpk.TypeTrees.Json` and `Tpk` project files.
2025-02-24 15:38:36 -08:00
dependabot[bot] 4a92302463 Bump NUnit.Analyzers from 4.3.0 to 4.6.0
Bumps [NUnit.Analyzers](https://github.com/nunit/nunit.analyzers) from 4.3.0 to 4.6.0.
- [Release notes](https://github.com/nunit/nunit.analyzers/releases)
- [Changelog](https://github.com/nunit/nunit.analyzers/blob/master/CHANGES.md)
- [Commits](https://github.com/nunit/nunit.analyzers/compare/4.3.0...4.6.0)

---
updated-dependencies:
- dependency-name: NUnit.Analyzers
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-02-15 23:45:20 -05:00
ds5678 687e194b29 Other package too 2024-11-10 12:11:18 -08:00
ds5678 c79a746c82 Bump version 2024-11-10 12:08:32 -08:00
dependabot[bot] 5f90031d63 Bump Microsoft.NET.Test.Sdk from 17.11.0 to 17.11.1
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.11.0 to 17.11.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.11.0...v17.11.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-10-01 13:44:23 -07:00
ds5678 85dbc3a79c NUnit 4 2024-09-02 10:29:37 -07:00
dependabot[bot] 4c533379d8 Bump SharpCompress from 0.37.2 to 0.38.0
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.37.2 to 0.38.0.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.37.2...0.38.0)

---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-09-02 10:03:20 -07:00
dependabot[bot] 1f4bd7c737 Bump AssetRipper.Primitives from 3.1.2 to 3.1.3
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-08-10 16:32:07 -07:00
dependabot[bot] 649af41f6e ---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-07-20 09:21:20 -07:00
dependabot[bot] e28e98a799 Bump coverlet.collector from 6.0.0 to 6.0.2
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 6.0.0 to 6.0.2.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.0...v6.0.2)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-06-23 04:36:03 -04:00
dependabot[bot] ba11e654cc Bump SharpCompress from 0.36.0 to 0.37.2
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.36.0 to 0.37.2.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.36.0...0.37.2)

---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-06-09 23:17:45 -04:00
dependabot[bot] b53cf51d5f Bump AssetRipper.Primitives from 3.1.1 to 3.1.2
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 3.1.1 to 3.1.2.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/3.1.1...3.1.2)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-05-31 12:30:13 -04:00
dependabot[bot] e5b8a97187 Bump AssetRipper.Primitives from 3.1.0 to 3.1.1
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/3.1.0...3.1.1)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-05-23 18:15:03 -04:00
dependabot[bot] 30c708de72 Bump AssetRipper.Primitives from 2.1.1 to 3.1.0
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 2.1.1 to 3.1.0.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/2.1.1...3.1.0)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-04-28 21:54:34 -07:00
dependabot[bot] b2cef3378c Bump SharpCompress from 0.34.1 to 0.36.0
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.34.1 to 0.36.0.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.34.1...0.36.0)

---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-04-15 08:05:49 -07:00
dependabot[bot] 4f916d2306 Bump K4os.Compression.LZ4 from 1.3.6 to 1.3.8
Bumps [K4os.Compression.LZ4](https://github.com/MiloszKrajewski/K4os.Compression.LZ4) from 1.3.6 to 1.3.8.
- [Release notes](https://github.com/MiloszKrajewski/K4os.Compression.LZ4/releases)
- [Changelog](https://github.com/MiloszKrajewski/K4os.Compression.LZ4/blob/master/CHANGES.md)
- [Commits](https://github.com/MiloszKrajewski/K4os.Compression.LZ4/compare/1.3.6...1.3.8)

---
updated-dependencies:
- dependency-name: K4os.Compression.LZ4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-04-14 12:54:57 -07:00
dependabot[bot] e887f78985 Bump Microsoft.NET.Test.Sdk from 17.7.2 to 17.8.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.2 to 17.8.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.7.2...v17.8.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-02-04 12:23:59 -05:00
dependabot[bot] 9b69284a02 Bump AssetRipper.Primitives from 2.1.0 to 2.1.1
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/2.1.0...2.1.1)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-01-18 09:11:44 -05:00
dependabot[bot] 17f1248adb Bump actions/upload-artifact from 3 to 4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-01-13 13:25:54 -05:00
dependabot[bot] 3e183b30d2 Bump AssetRipper.Primitives from 2.0.1 to 2.1.0
Bumps [AssetRipper.Primitives](https://github.com/AssetRipper/AssetRipper.Primitives) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/AssetRipper/AssetRipper.Primitives/releases)
- [Commits](https://github.com/AssetRipper/AssetRipper.Primitives/compare/2.0.1.0...2.1.0)

---
updated-dependencies:
- dependency-name: AssetRipper.Primitives
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-22 20:41:39 -05:00
dependabot[bot] 437de4efe2 Bump Microsoft.SourceLink.GitHub from 1.1.1 to 8.0.0
Bumps [Microsoft.SourceLink.GitHub](https://github.com/dotnet/sourcelink) from 1.1.1 to 8.0.0.
- [Release notes](https://github.com/dotnet/sourcelink/releases)
- [Commits](https://github.com/dotnet/sourcelink/commits)

---
updated-dependencies:
- dependency-name: Microsoft.SourceLink.GitHub
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-09 17:30:18 -05:00
dependabot[bot] 1d591f37c7 Bump actions/setup-dotnet from 3 to 4
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3 to 4.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-04 14:22:23 -05:00
dependabot[bot] 2ce99d2bce Bump NUnit from 3.13.3 to 3.14.0
Bumps [NUnit](https://github.com/nunit/nunit) from 3.13.3 to 3.14.0.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/v3.13.3...v3.14.0)

---
updated-dependencies:
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-06 11:19:06 -05:00
Jeremy Pritts ef529e43d3 Add more links to the readme 2023-10-09 12:09:20 -04:00
38 changed files with 396 additions and 507 deletions

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
[*.{cs,vb}]
tab_width = 4
indent_size = 4
end_of_line = lf
indent_style = tab
-63
View File
@@ -1,63 +0,0 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
+10 -10
View File
@@ -27,45 +27,45 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Tpk Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v6
with:
dotnet-version: 6.0.x
dotnet-version: 10.0.x
- name: Build
run: dotnet build /p:Configuration=Release
working-directory: ./Tpk.ConsoleApp/
- name: Checkout DocumentationDumps Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
repository: 'AssetRipper/DocumentationDumps'
path: DocumentationDumps
- name: Make files executable
shell: bash
run: chmod +x ./Tpk.ConsoleApp/bin/Release/net6.0/AssetRipper.Tpk.ConsoleApp
run: chmod +x ./Tpk.ConsoleApp/bin/Release/net10.0/AssetRipper.Tpk.ConsoleApp
- name: Make tpk file
shell: bash
run: ./Tpk.ConsoleApp/bin/Release/net6.0/AssetRipper.Tpk.ConsoleApp --engine-assets ./DocumentationDumps/EngineAssets
run: ./Tpk.ConsoleApp/bin/Release/net10.0/AssetRipper.Tpk.ConsoleApp --engine-assets ./DocumentationDumps/EngineAssets
- name: Upload Uncompressed file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: uncompressed_file
path: ./uncompressed.tpk
if-no-files-found: error
- name: Upload Lz4 file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: lz4_file
path: ./lz4.tpk
if-no-files-found: error
- name: Upload Lzma file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: lzma_file
path: ./lzma.tpk
if-no-files-found: error
- name: Upload Brotli file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: brotli_file
path: ./brotli.tpk
+3 -3
View File
@@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v6
with:
dotnet-version: 6.0.x
dotnet-version: 10.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
+12 -11
View File
@@ -27,47 +27,48 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Tpk Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v6
with:
dotnet-version: 6.0.x
dotnet-version: 10.0.x
- name: Build
run: dotnet build /p:Configuration=Release
working-directory: ./Tpk.ConsoleApp/
- name: Checkout TypeTreeDumps Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
repository: 'AssetRipper/TypeTreeDumps'
sparse-checkout: 'InfoJson'
path: TypeTreeDumps
- name: Make files executable
shell: bash
run: chmod +x ./Tpk.ConsoleApp/bin/Release/net6.0/AssetRipper.Tpk.ConsoleApp
run: chmod +x ./Tpk.ConsoleApp/bin/Release/net10.0/AssetRipper.Tpk.ConsoleApp
- name: Make tpk file
shell: bash
run: ./Tpk.ConsoleApp/bin/Release/net6.0/AssetRipper.Tpk.ConsoleApp --type-tree ./TypeTreeDumps/InfoJson
run: ./Tpk.ConsoleApp/bin/Release/net10.0/AssetRipper.Tpk.ConsoleApp --type-tree ./TypeTreeDumps/InfoJson
- name: Upload Uncompressed file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: uncompressed_file
path: ./uncompressed.tpk
if-no-files-found: error
- name: Upload Lz4 file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: lz4_file
path: ./lz4.tpk
if-no-files-found: error
- name: Upload Lzma file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: lzma_file
path: ./lzma.tpk
if-no-files-found: error
- name: Upload Brotli file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v7
with:
name: brotli_file
path: ./brotli.tpk
if-no-files-found: error
+19
View File
@@ -0,0 +1,19 @@
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAotCompatible>true</IsAotCompatible>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<VersionPrefix>2.0.0</VersionPrefix>
<RepositoryUrl>https://github.com/AssetRipper/Tpk</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<Copyright>Copyright (c) ds5678</Copyright>
</PropertyGroup>
</Project>
+12 -8
View File
@@ -4,18 +4,22 @@ A tool for compressing [type tree dumps](https://github.com/AssetRipper/TypeTree
## Type Tree Tpk
> Warning: [AssetsTools.NET](https://github.com/nesrak1/AssetsTools.NET) does not support Brotli compression.
| Compression | Link |
| ----------- | ---- |
| Brotli | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/brotli_file.zip |
| Lz4 | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/lz4_file.zip |
| LZMA | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/lzma_file.zip |
| Uncompressed | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/uncompressed_file.zip |
| [Brotli](https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/brotli_file) | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/brotli_file.zip |
| [Lz4](https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/lz4_file) | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/lz4_file.zip |
| [LZMA](https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/lzma_file) | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/lzma_file.zip |
| [Uncompressed](https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/uncompressed_file) | https://nightly.link/AssetRipper/Tpk/workflows/type_tree_tpk/master/uncompressed_file.zip |
## Engine Assets Tpk
> This is an internal file for AssetRipper and might not have much other use.
| Compression | Link |
| ----------- | ---- |
| Brotli | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/brotli_file.zip |
| Lz4 | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/lz4_file.zip |
| LZMA | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/lzma_file.zip |
| Uncompressed | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/uncompressed_file.zip |
| [Brotli](https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/brotli_file) | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/brotli_file.zip |
| [Lz4](https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/lz4_file) | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/lz4_file.zip |
| [LZMA](https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/lzma_file) | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/lzma_file.zip |
| [Uncompressed](https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/uncompressed_file) | https://nightly.link/AssetRipper/Tpk/workflows/engine_assets_tpk/master/uncompressed_file.zip |
+2 -9
View File
@@ -2,20 +2,13 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>AssetRipper.Tpk.ConsoleApp</RootNamespace>
<AssemblyName>AssetRipper.Tpk.ConsoleApp</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpZipLib" Version="1.4.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tpk.TypeTrees.Json\Tpk.TypeTrees.Json.csproj" />
<ProjectReference Include="..\Tpk\Tpk.csproj" />
<ProjectReference Include="..\Tpk.TypeTrees.Json\Tpk.TypeTrees.Json.csproj" />
<ProjectReference Include="..\Tpk\Tpk.csproj" />
</ItemGroup>
</Project>
+37 -28
View File
@@ -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;
}
}
+16 -30
View File
@@ -1,7 +1,9 @@
using System.Collections.Generic;
using AssetRipper.Primitives;
using AssetRipper.Tpk.TypeTrees.Json;
using AssetRipper.Primitives;
using ICSharpCode.SharpZipLib.Zip;
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using SharpCompress.Writers.Zip;
using System.Collections.Generic;
namespace AssetRipper.Tpk.ConsoleApp
{
@@ -12,48 +14,32 @@ 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 ZipInputStream zipInputStream = new ZipInputStream(fileStream);
ZipEntry entry;
while ((entry = zipInputStream.GetNextEntry()) is not null)
using IWritableArchive<ZipWriterOptions> archive = ZipArchive.OpenArchive(fileStream);
foreach (var entry in archive.Entries)
{
if(entry.IsFile && entry.Name.EndsWith(".json", StringComparison.Ordinal))
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();
zipInputStream.CopyTo(unzippedFileStream);
entry.WriteTo(unzippedFileStream);
unzippedFileStream.Position = 0;
UnityInfo? info = UnityInfo.FromStream(unzippedFileStream);
if(info is not null)
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);
}
}
}
+3 -3
View File
@@ -14,7 +14,7 @@ namespace AssetRipper.Tpk.Tests
if (compressedData.Length == 0)
Assert.Fail("Compressed data cannot be empty");
byte[] decompressedData = BrotliHandler.Decompress(compressedData);
Assert.AreEqual(randomData, decompressedData);
Assert.That(decompressedData, Is.EqualTo(randomData));
}
[Test]
@@ -24,7 +24,7 @@ namespace AssetRipper.Tpk.Tests
if (compressedData.Length == 0)
Assert.Fail("Compressed data cannot be empty");
byte[] decompressedData = Lz4Handler.Decompress(compressedData, randomData.Length);
Assert.AreEqual(randomData, decompressedData);
Assert.That(decompressedData, Is.EqualTo(randomData));
}
[Test]
@@ -34,7 +34,7 @@ namespace AssetRipper.Tpk.Tests
if (compressedData.Length == 0)
Assert.Fail("Compressed data cannot be empty");
byte[] decompressedData = LzmaHandler.Decompress(compressedData, randomData.Length);
Assert.AreEqual(randomData, decompressedData);
Assert.That(decompressedData, Is.EqualTo(randomData));
}
}
}
+12 -6
View File
@@ -19,9 +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.AreEqual(originalBlob.CreationTime, readBlob.CreationTime);
Assert.AreEqual(originalBlob.Versions, readBlob.Versions);
Assert.AreEqual(originalBlob.Data, readBlob.Data);
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]
@@ -30,8 +33,11 @@ public class EngineAssetsTests
TpkEngineAssetsBlob originalBlob = new();
byte[] writtenData = originalBlob.ToBinary();
TpkEngineAssetsBlob readBlob = TpkDataBlob.FromBinary<TpkEngineAssetsBlob>(writtenData);
Assert.AreEqual(originalBlob.CreationTime, readBlob.CreationTime);
Assert.AreEqual(originalBlob.Versions, readBlob.Versions);
Assert.AreEqual(originalBlob.Data, readBlob.Data);
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 -1
View File
@@ -10,7 +10,7 @@ namespace AssetRipper.Tpk.Tests
TpkFileSystemBlob originalBlob = BlobCreator.MakeRandomFileSystemBlob();
byte[] writtenData = originalBlob.ToBinary();
TpkFileSystemBlob readBlob = TpkDataBlob.FromBinary<TpkFileSystemBlob>(writtenData);
Assert.AreEqual(originalBlob.Files, readBlob.Files);
Assert.That(readBlob.Files, Is.EqualTo(originalBlob.Files));
}
}
}
+2 -2
View File
@@ -11,7 +11,7 @@ namespace AssetRipper.Tpk.Tests
originalBlob.Text = RandomUtils.RandomString(557);
byte[] writtenData = originalBlob.ToBinary();
TpkJsonBlob readBlob = TpkDataBlob.FromBinary<TpkJsonBlob>(writtenData);
Assert.AreEqual(originalBlob.Text, readBlob.Text);
Assert.That(readBlob.Text, Is.EqualTo(originalBlob.Text));
}
[Test]
@@ -20,7 +20,7 @@ namespace AssetRipper.Tpk.Tests
TpkJsonBlob originalBlob = new TpkJsonBlob();
byte[] writtenData = originalBlob.ToBinary();
TpkJsonBlob readBlob = TpkDataBlob.FromBinary<TpkJsonBlob>(writtenData);
Assert.AreEqual(originalBlob.Text, readBlob.Text);
Assert.That(readBlob.Text, Is.EqualTo(originalBlob.Text));
}
}
}
+9 -8
View File
@@ -1,19 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>AssetRipper.Tpk.Tests</RootNamespace>
<AssemblyName>AssetRipper.Tpk.Tests</AssemblyName>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.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="10.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
+7 -4
View File
@@ -9,10 +9,13 @@ namespace AssetRipper.Tpk.Tests
{
TpkFile file = CreateTpkFile();
byte[] data = file.WriteToMemory();
Assert.AreEqual((byte)'T', data[0]);
Assert.AreEqual((byte)'P', data[1]);
Assert.AreEqual((byte)'K', data[2]);
Assert.AreEqual((byte)'*', data[3]);
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()
+35 -12
View File
@@ -1,6 +1,7 @@
using AssetRipper.Tpk.TypeTrees;
using AssetRipper.Primitives;
using AssetRipper.Primitives;
using AssetRipper.Tpk.TypeTrees;
using NUnit.Framework;
using System.IO;
namespace AssetRipper.Tpk.Tests.TypeTrees
{
@@ -9,32 +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.AreEqual(0, commonString.GetCount(Unity5));
Assert.That(commonString.GetEntries(Unity5), Is.Empty);
}
[Test]
public static void CountIsCorrectForNormalUse()
{
TpkCommonString commonString = MakeCommonString();
Assert.AreEqual(5, commonString.GetCount(Unity3));
Assert.AreEqual(5, commonString.GetCount(Unity4));
Assert.AreEqual(5, commonString.GetCount(Unity5));
Assert.AreEqual(10, commonString.GetCount(Unity6));
Assert.AreEqual(10, commonString.GetCount(Unity7));
using (Assert.EnterMultipleScope())
{
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;
}
}
@@ -1,19 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>AssetRipper.Tpk.TypeTrees.Json.Tests</RootNamespace>
<AssemblyName>AssetRipper.Tpk.TypeTrees.Json.Tests</AssemblyName>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.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="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;
+4 -18
View File
@@ -1,36 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsTrimmable>true</IsTrimmable>
<RootNamespace>AssetRipper.Tpk.TypeTrees.Json</RootNamespace>
<AssemblyName>AssetRipper.Tpk.TypeTrees.Json</AssemblyName>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<Version>1.0.0</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<PackageId>AssetRipper.Tpk.TypeTrees.Json</PackageId>
<PackageTags>C#</PackageTags>
<RepositoryUrl>https://github.com/AssetRipper/Tpk</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<Copyright>Copyright (c) 2023 ds5678</Copyright>
<Description>Library for type tree serialization.</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AssetRipper.HashAlgorithms" Version="1.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.301">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
+21 -28
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,26 +33,20 @@ 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/>
/// However, some older unity versions don't generate this, so sometimes we have to set it in SharedState initialization
/// However, some older unity versions don't generate this, so sometimes it needs to be set manually.
/// </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 -32
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,42 +10,39 @@ namespace AssetRipper.Tpk.TypeTrees.Json
{
public sealed class UnityNode
{
/// <summary>
/// The unique type name used in the <see cref = "SharedState"/> dictionaries
/// </summary>
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/>
@@ -53,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);
}
}
}
-66
View File
@@ -1,66 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B80E65C0-145A-4034-9EC8-E2D03ECAE732}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
License.md = License.md
README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{33E54A6F-8689-4D4A-AA4F-CB68BDEE8FF4}"
ProjectSection(SolutionItems) = preProject
.github\workflows\engine_assets_tpk.yml = .github\workflows\engine_assets_tpk.yml
.github\workflows\test.yml = .github\workflows\test.yml
.github\workflows\type_tree_tpk.yml = .github\workflows\type_tree_tpk.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tpk", "Tpk\Tpk.csproj", "{E209C981-9B4C-4F85-94D1-BE3BE279FFE9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tpk.ConsoleApp", "Tpk.ConsoleApp\Tpk.ConsoleApp.csproj", "{C72B5264-B6E5-4182-A0D1-D0D95D310C26}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tpk.Tests", "Tpk.Tests\Tpk.Tests.csproj", "{35439820-AA58-4808-9CB0-C749A72E6E84}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tpk.TypeTrees.Json", "Tpk.TypeTrees.Json\Tpk.TypeTrees.Json.csproj", "{7EE04F87-29D5-40C1-A844-E69E22A0EC2F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tpk.TypeTrees.Json.Tests", "Tpk.TypeTrees.Json.Tests\Tpk.TypeTrees.Json.Tests.csproj", "{4D312207-79EB-4289-A855-9517AD25AD88}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E209C981-9B4C-4F85-94D1-BE3BE279FFE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E209C981-9B4C-4F85-94D1-BE3BE279FFE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E209C981-9B4C-4F85-94D1-BE3BE279FFE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E209C981-9B4C-4F85-94D1-BE3BE279FFE9}.Release|Any CPU.Build.0 = Release|Any CPU
{C72B5264-B6E5-4182-A0D1-D0D95D310C26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C72B5264-B6E5-4182-A0D1-D0D95D310C26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C72B5264-B6E5-4182-A0D1-D0D95D310C26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C72B5264-B6E5-4182-A0D1-D0D95D310C26}.Release|Any CPU.Build.0 = Release|Any CPU
{35439820-AA58-4808-9CB0-C749A72E6E84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35439820-AA58-4808-9CB0-C749A72E6E84}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35439820-AA58-4808-9CB0-C749A72E6E84}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35439820-AA58-4808-9CB0-C749A72E6E84}.Release|Any CPU.Build.0 = Release|Any CPU
{7EE04F87-29D5-40C1-A844-E69E22A0EC2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EE04F87-29D5-40C1-A844-E69E22A0EC2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EE04F87-29D5-40C1-A844-E69E22A0EC2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EE04F87-29D5-40C1-A844-E69E22A0EC2F}.Release|Any CPU.Build.0 = Release|Any CPU
{4D312207-79EB-4289-A855-9517AD25AD88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D312207-79EB-4289-A855-9517AD25AD88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D312207-79EB-4289-A855-9517AD25AD88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D312207-79EB-4289-A855-9517AD25AD88}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{33E54A6F-8689-4D4A-AA4F-CB68BDEE8FF4} = {B80E65C0-145A-4034-9EC8-E2D03ECAE732}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B4F6071A-E37E-4782-9BDD-92C8A73D4820}
EndGlobalSection
EndGlobal
+19
View File
@@ -0,0 +1,19 @@
<Solution>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
<File Path=".gitignore" />
<File Path="Directory.Build.props" />
<File Path="License.md" />
<File Path="README.md" />
</Folder>
<Folder Name="/Solution Items/workflows/">
<File Path=".github/workflows/engine_assets_tpk.yml" />
<File Path=".github/workflows/test.yml" />
<File Path=".github/workflows/type_tree_tpk.yml" />
</Folder>
<Project Path="Tpk.ConsoleApp/Tpk.ConsoleApp.csproj" />
<Project Path="Tpk.Tests/Tpk.Tests.csproj" />
<Project Path="Tpk.TypeTrees.Json.Tests/Tpk.TypeTrees.Json.Tests.csproj" />
<Project Path="Tpk.TypeTrees.Json/Tpk.TypeTrees.Json.csproj" />
<Project Path="Tpk/Tpk.csproj" />
</Solution>
+3 -3
View File
@@ -9,7 +9,7 @@ namespace AssetRipper.Tpk.Compression
LzmaEncoderProperties properties = new LzmaEncoderProperties(false, 1 << 25, 256);
using MemoryStream inputStream = new MemoryStream(uncompressedBytes);
using MemoryStream outputStream = new MemoryStream();
using LzmaStream lzmaStream = new LzmaStream(properties, false, outputStream);
using LzmaStream lzmaStream = LzmaStream.Create(properties, false, outputStream);
outputStream.Write(lzmaStream.Properties);
inputStream.CopyTo(lzmaStream);
lzmaStream.Close();
@@ -25,7 +25,7 @@ namespace AssetRipper.Tpk.Compression
using MemoryStream inputStream = new MemoryStream(compressedBytes);
inputStream.Position = 5;
using MemoryStream outputStream = new MemoryStream();
using LzmaStream lzmaStream = new LzmaStream(properties, inputStream, compressedBytes.Length - 5, decompressedSize);
using LzmaStream lzmaStream = LzmaStream.Create(properties, inputStream, compressedBytes.Length - 5, decompressedSize);
lzmaStream.CopyTo(outputStream);
return outputStream.ToArray();
}
@@ -38,7 +38,7 @@ namespace AssetRipper.Tpk.Compression
byte[] properties = new Span<byte>(compressedBytes, 0, 5).ToArray();
MemoryStream inputStream = new MemoryStream(compressedBytes);
inputStream.Position = 5;
return new LzmaStream(properties, inputStream, compressedBytes.Length - 5, decompressedSize);
return LzmaStream.Create(properties, inputStream, compressedBytes.Length - 5, decompressedSize);
}
}
}
+6 -20
View File
@@ -1,41 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsTrimmable>true</IsTrimmable>
<RootNamespace>AssetRipper.Tpk</RootNamespace>
<AssemblyName>AssetRipper.Tpk</AssemblyName>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<Version>1.0.0</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<PackageId>AssetRipper.Tpk</PackageId>
<PackageTags>C#</PackageTags>
<RepositoryUrl>https://github.com/AssetRipper/Tpk</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<Copyright>Copyright (c) 2023 ds5678</Copyright>
<Description>Library for storing asset information.</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AssetRipper.Primitives" Version="2.0.1" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.6" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<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.301">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SharpCompress" Version="0.34.1" />
<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;
+1 -1
View File
@@ -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; }
+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)
{
+50 -45
View File
@@ -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);
}
}
}
}
-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);
}
}
}