33 Commits
Author SHA1 Message Date
ds5678 51873aaef9 Bump version 2024-08-28 21:27:29 -07:00
ds5678 a43a560f9a Use string instead of UnityGuid on NET Standard 2024-08-28 21:27:23 -07:00
ds5678 54eb41b856 EngineResourceData deserialization improvements 2024-08-15 21:49:21 -07:00
ds5678 2b22375c90 Improve Unity 2 and 3 support 2024-06-01 08:41:50 -07:00
ds5678 d989f9f16a Use SerializableValue indexer property 2024-05-31 20:36:45 -07:00
ds5678 19fb8b36dd Small name fix 2024-05-31 20:25:09 -07:00
aldelaro5 9479c1aa66 Init the aabb part of the mesh key (#3) 2024-05-31 20:09:41 -07:00
ds5678 5bb396ffda Make the internal serializer context public
* Add tests for Vector3 serialization and deserialization
* Bump AssetRipper.Primitives
2024-05-31 07:55:33 -07:00
ds5678 e014834c04 Bump version 2024-05-30 21:46:13 -07:00
ds5678 bf8806c154 Include fields for serialization 2024-05-30 21:44:21 -07:00
ds5678 40841a3c19 Bump AssetRipper.Mining.PredefinedAssets version 2024-05-30 21:22:58 -07:00
aldelaro5 a0fc1e8bc9 Add the AABB fields in the key of meshes (#2) 2024-05-30 21:19:22 -07:00
ds5678 5832762d66 Add reference assembly data 2024-05-30 21:04:58 -07:00
ds5678 cfcbb3e7ba More forgiving about MonoScript fields 2024-05-30 08:22:50 -07:00
ds5678 a3dfe6341b Switch from AssetsTools to the internal AssetRipper libaries 2024-05-30 00:33:42 -07:00
ds5678 bd12d9eae3 Resolve #1 2024-05-27 11:50:52 -07:00
ds5678 87328aaac2 Bump references 2024-05-27 11:12:44 -07:00
ds5678 9ca9112942 AssetDictionary.TryAdd and bump version 2024-01-18 10:36:26 -05:00
ds5678 8e0f803787 Bump version 2024-01-18 09:07:06 -05:00
ds5678 f01470f867 Use a dictionary for package assets, including scripts 2024-01-18 09:05:08 -05:00
ds5678 ab8b136b19 MonoScript.FromType 2024-01-18 08:57:28 -05:00
ds5678 e9b0003601 Fix UInt128 bugs 2024-01-18 08:24:58 -05:00
ds5678 9e2097dd81 API for adding assets to package data 2024-01-18 08:23:19 -05:00
ds5678 63316d5977 Rename Meta to Type 2024-01-16 03:25:48 -05:00
ds5678 0bfce878cb bump version 2024-01-16 02:43:25 -05:00
ds5678 8c56291f96 Add constructors that set required properties 2024-01-16 02:40:03 -05:00
ds5678 5798136567 Change mesh format 2024-01-16 02:39:31 -05:00
ds5678 18b456e6b8 Editor config 2024-01-16 02:38:28 -05:00
ds5678 d077b228d6 Fix UnityPackageData 2024-01-16 02:16:34 -05:00
ds5678 c34f7447b8 Bump version
* Add constructors to EngineResourceData and UnityPackageData
* Make UnityPackageData.Assets a dictionary
2024-01-16 00:35:31 -05:00
ds5678 c009d0cab9 Use string version in UnityPackageData and bump version 2024-01-15 20:36:30 -05:00
ds5678 f5d62fccf5 Bump version 2024-01-15 01:14:31 -05:00
ds5678 68a7e1fd2b Add more framework targets 2024-01-15 01:11:04 -05:00
35 changed files with 1022 additions and 171 deletions

No files matched your search

+258
View File
@@ -0,0 +1,258 @@
# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = tab
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline =true
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = false:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = false:silent
dotnet_style_prefer_conditional_expression_over_return = false:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:suggestion
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:warning
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_when_type_is_apparent = false:suggestion
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
# Code-block preferences
csharp_prefer_braces = true:suggestion
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_null_check_over_type_check = true:suggestion
csharp_style_prefer_local_over_anonymous_function = true:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_prefer_tuple_swap = true:suggestion
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
csharp_style_prefer_parameter_null_checking = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_extended_property_pattern = true:suggestion
csharp_style_prefer_top_level_statements = false:silent
dotnet_diagnostic.CA1309.severity = error
dotnet_diagnostic.CA1311.severity = suggestion
dotnet_diagnostic.SYSLIB1054.severity = warning
csharp_style_prefer_primary_constructors = false:silent
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_prefer_readonly_struct = true:suggestion
csharp_style_prefer_readonly_struct_member = true:suggestion
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
[*.{cs,vb}]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_object_initializer = false:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = lf
dotnet_style_prefer_conditional_expression_over_assignment = false:silent
dotnet_style_prefer_conditional_expression_over_return = false:silent
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_readonly_field = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
dotnet_code_quality_unused_parameters = all:suggestion
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent
dotnet_style_prefer_collection_expression = true:suggestion
@@ -1,18 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AssetsTools.NET" Version="3.0.0-preview3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetRipper.Mining.PredefinedAssets\AssetRipper.Mining.PredefinedAssets.csproj" />
<ProjectReference Include="..\..\AssetRipper\Source\AssetRipper.Import\AssetRipper.Import.csproj" />
</ItemGroup>
</Project>
@@ -1,12 +0,0 @@
using AssetsTools.NET;
namespace AssetRipper.Mining.EngineFileExtractor;
internal static class AssetTypeValueFieldExtensions
{
public static AssetTypeValueField? TryGet(this AssetTypeValueField @this, string name)
{
AssetTypeValueField result = @this.Get(name);
return result.IsDummy ? null : result;
}
}
+66 -108
View File
@@ -1,7 +1,15 @@
using AssetRipper.Mining.PredefinedAssets;
using AssetsTools.NET;
using AssetsTools.NET.Extra;
using System.Diagnostics;
using AssetRipper.Assets;
using AssetRipper.Assets.Bundles;
using AssetRipper.Assets.Collections;
using AssetRipper.Assets.Generics;
using AssetRipper.Assets.IO;
using AssetRipper.Assets.Metadata;
using AssetRipper.Import.AssetCreation;
using AssetRipper.Import.Structure.Assembly.Serializable;
using AssetRipper.Import.Structure.Assembly.TypeTrees;
using AssetRipper.IO.Endian;
using AssetRipper.IO.Files.SerializedFiles.Parser;
using AssetRipper.Mining.PredefinedAssets;
using Object = AssetRipper.Mining.PredefinedAssets.Object;
namespace AssetRipper.Mining.EngineFileExtractor;
@@ -40,32 +48,52 @@ internal static class Program
private static Dictionary<long, Object> ReadDictionary(string path)
{
if (!File.Exists(path))
{
return [];
}
return LoadAllAssetInfo(path).OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
}
private static IEnumerable<UnityAsset> LoadAllAssets(string path)
private static AssetCollection LoadAllAssets(string path)
{
AssetsManager manager = new();
AssetsFileInstance assetsFileInstance = manager.LoadAssetsFile(path, false);
foreach (AssetFileInfo assetFileInfo in assetsFileInstance.file.AssetInfos)
return GameBundle.FromPaths([path], TypeTreeAssetFactory.Instance).FetchAssetCollections().Single();
}
private sealed class TypeTreeAssetFactory : AssetFactoryBase
{
public static TypeTreeAssetFactory Instance { get; } = new();
public override IUnityObjectBase? ReadAsset(AssetInfo assetInfo, ReadOnlyArraySegment<byte> assetData, SerializedType? assetType)
{
yield return new UnityAsset(manager, assetsFileInstance, assetFileInfo);
ArgumentNullException.ThrowIfNull(assetType);
ArgumentOutOfRangeException.ThrowIfZero(assetType.OldType.Nodes.Count);
if (!TypeTreeNodeStruct.TryMakeFromTypeTree(assetType.OldType, out TypeTreeNodeStruct root))
{
throw new NotSupportedException("Type tree node struct creation failed");
}
else
{
TypeTreeObject asset = TypeTreeObject.Create(assetInfo, root);
EndianSpanReader reader = new(assetData, assetInfo.Collection.EndianType);
asset.Read(ref reader);
return asset;
}
}
}
private static IEnumerable<KeyValuePair<long, Object>> LoadAllAssetInfo(string path)
{
foreach (UnityAsset asset in LoadAllAssets(path))
foreach (TypeTreeObject asset in LoadAllAssets(path).Cast<TypeTreeObject>())
{
Object obj;
switch (asset.TypeID)
switch (asset.ClassID)
{
case 21://Material
{
obj = new Material()
{
Name = asset.Name,
Shader = asset.TryGetAsset("m_Shader")?.Name
Name = asset.Name(),
Shader = asset.TryGetAsset("m_Shader")?.Name()
};
}
break;
@@ -73,7 +101,7 @@ internal static class Program
{
obj = new Texture2D()
{
Name = asset.Name,
Name = asset.Name(),
Height = asset.GetInt32("m_Height"),
Width = asset.GetInt32("m_Width")
};
@@ -83,39 +111,43 @@ internal static class Program
{
obj = new Mesh()
{
Name = asset.Name,
VertexCount = asset.BaseField.Get("m_VertexData").Get("m_VertexCount").AsUInt
Name = asset.Name(),
VertexCount = asset.ReleaseFields.ContainsField("m_VertexData")
? asset.ReleaseFields["m_VertexData"]["m_VertexCount"].AsInt32
: asset.ReleaseFields["m_CompressedMesh"]["m_Vertices"]["m_NumItems"].AsInt32,
SubMeshCount = asset.ReleaseFields["m_SubMeshes"].AsAssetArray.Length,
LocalAABB = asset.ReleaseFields["m_LocalAABB"].AsAxisAlignedBoundingBox(),
};
}
break;
case 48://Shader
{
string[] propertyNames;
AssetTypeValueField serializedShader = asset.BaseField.Get("m_ParsedForm");
if (serializedShader.IsDummy)
SerializableStructure? serializedShader = asset.ReleaseFields.TryGetField("m_ParsedForm")?.AsStructure;
if (serializedShader is null)
{
propertyNames = Array.Empty<string>();
}
else
{
List<AssetTypeValueField> propsList = serializedShader.Get("m_PropInfo").Get("m_Props").Get("Array").Children;
if (propsList.Count == 0)
IUnityAssetBase[] propsList = serializedShader["m_PropInfo"]["m_Props"].AsAssetArray;
if (propsList.Length == 0)
{
propertyNames = Array.Empty<string>();
}
else
{
propertyNames = new string[propsList.Count];
for (int i = 0; i < propsList.Count; i++)
propertyNames = new string[propsList.Length];
for (int i = 0; i < propsList.Length; i++)
{
propertyNames[i] = propsList[i].Get("m_Name").AsString ?? "";
propertyNames[i] = ((SerializableStructure)propsList[i])["m_Name"].AsString;
}
}
}
obj = new Shader()
{
Name = asset.Name,
Name = asset.Name(),
PropertyNames = propertyNames
};
}
@@ -126,7 +158,7 @@ internal static class Program
{
obj = new Cubemap()
{
Name = asset.Name,
Name = asset.Name(),
Height = asset.GetInt32("m_Height"),
Width = asset.GetInt32("m_Width")
};
@@ -134,14 +166,14 @@ internal static class Program
break;
case 114://MonoBehaviour
{
UnityAsset? script = asset.TryGetAsset("m_Script");
TypeTreeObject? script = asset.TryGetAsset("m_Script");
obj = new MonoBehaviour()
{
Name = asset.Name,
AssemblyName = script?.GetString("m_AssemblyName") ?? "",
Name = asset.Name(),
AssemblyName = script?.TryGetString("m_AssemblyName") ?? "",
Namespace = script?.GetString("m_Namespace") ?? "",
ClassName = script?.GetString("m_ClassName") ?? "",
GameObject = asset.TryGetAsset("m_GameObject")?.Name,
GameObject = asset.TryGetAsset("m_GameObject")?.Name(),
Enabled = asset.GetBoolean("m_Enabled")
};
}
@@ -150,7 +182,7 @@ internal static class Program
{
obj = new MonoScript()
{
AssemblyName = asset.GetString("m_AssemblyName"),
AssemblyName = asset.TryGetString("m_AssemblyName") ?? "",
Namespace = asset.GetString("m_Namespace"),
ClassName = asset.GetString("m_ClassName")
};
@@ -162,8 +194,8 @@ internal static class Program
{
obj = new Sprite()
{
Name = asset.Name,
Texture = asset.ResolveAsset(asset.BaseField.Get("m_RD").Get("texture"))?.Name,
Name = asset.Name(),
Texture = asset.ResolveAsset(asset.ReleaseFields["m_RD"]["texture"].AsPPtr)?.Name(),
};
}
break;
@@ -172,86 +204,12 @@ internal static class Program
default:
obj = new GenericNamedObject()
{
TypeID = asset.TypeID,
Name = asset.Name
TypeID = asset.ClassID,
Name = asset.Name()
};
break;
}
yield return new KeyValuePair<long, Object>(asset.PathID, obj);
}
}
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
private readonly struct UnityAsset
{
private readonly AssetsManager manager;
private readonly AssetsFileInstance file;
private readonly AssetFileInfo info;
public UnityAsset(AssetsManager manager, AssetsFileInstance file, AssetFileInfo info)
{
this.manager = manager;
this.file = file;
this.info = info;
}
public int TypeID
{
get
{
int result = info.TypeId;
return result < 0 ? 114 : result;
}
}
public long PathID => info.PathId;
public string Name
{
get
{
AssetTypeValueField baseField = BaseField;
string? name = baseField.TryGet("m_Name")?.AsString;
if (string.IsNullOrEmpty(name) && TypeID == 48)//Shader
{
name = baseField.TryGet("m_ParsedForm")?.TryGet("m_Name")?.AsString //5.5 and later
?? baseField.TryGet("m_PathName")?.AsString; //Earlier than 5.5
if (string.IsNullOrEmpty(name)
&& (baseField.TryGet("m_Script")?.AsString?.StartsWith("Shader \"Standard\"", StringComparison.Ordinal) ?? false))
{
//A regex could be used to generalize, but as far as I know, Standard is the only one like this.
name = "Standard";
}
}
return name ?? "";
}
}
public string GetString(string fieldName) => BaseField.TryGet(fieldName)?.AsString ?? "";
public int GetInt32(string fieldName) => BaseField.Get(fieldName).AsInt;
public bool GetBoolean(string fieldName) => BaseField.Get(fieldName).AsBool;
public UnityAsset? TryGetAsset(string fieldName)
{
return ResolveAsset(BaseField.Get(fieldName));
}
public UnityAsset? ResolveAsset(AssetTypeValueField pptrField)
{
AssetExternal assetExternal = manager.GetExtAsset(file, pptrField);
return assetExternal.file is null || assetExternal.info is null
? null
: new UnityAsset(manager, assetExternal.file, assetExternal.info);
}
public AssetTypeValueField BaseField => manager.GetBaseField(file, info);
private string GetDebuggerDisplay()
{
return $"{TypeID} : {Name}";
}
}
}
@@ -0,0 +1,18 @@
using AssetRipper.Import.Structure.Assembly.Serializable;
using AssetRipper.Mining.PredefinedAssets;
using System.Numerics;
namespace AssetRipper.Mining.EngineFileExtractor;
internal static class SerializableValueExtensions
{
public static Vector3 AsVector3(this SerializableValue value)
{
return new Vector3(value["x"].AsSingle, value["y"].AsSingle, value["z"].AsSingle);
}
public static AxisAlignedBoundingBox AsAxisAlignedBoundingBox(this SerializableValue value)
{
return new AxisAlignedBoundingBox(value["m_Center"].AsVector3(), value["m_Extent"].AsVector3());
}
}
@@ -0,0 +1,59 @@
using AssetRipper.Assets.Metadata;
using AssetRipper.Import.AssetCreation;
using AssetRipper.Import.Structure.Assembly.Serializable;
namespace AssetRipper.Mining.EngineFileExtractor;
internal static class TypeTreeObjectExtensions
{
public static string Name(this TypeTreeObject asset)
{
SerializableStructure baseField = asset.ReleaseFields;
string? name = baseField.TryGetField("m_Name")?.AsString;
if (string.IsNullOrEmpty(name) && asset.ClassID == 48)//Shader
{
name = baseField.TryGetField("m_ParsedForm")?.AsStructure.TryGetField("m_Name")?.AsString //5.5 and later
?? baseField.TryGetField("m_PathName")?.AsString; //Earlier than 5.5
if (string.IsNullOrEmpty(name)
&& (baseField.TryGetField("m_Script")?.AsString?.StartsWith("Shader \"Standard\"", StringComparison.Ordinal) ?? false))
{
//A regex could be used to generalize, but as far as I know, Standard is the only one like this.
name = "Standard";
}
}
return name ?? "";
}
public static TypeTreeObject? TryGetAsset(this TypeTreeObject asset, string fieldName)
{
return asset.ReleaseFields.TryGetField(fieldName)?.AsAsset is IPPtr pptr
? asset.ResolveAsset(pptr)
: null;
}
public static bool GetBoolean(this TypeTreeObject asset, string fieldName)
{
return asset.ReleaseFields[fieldName].AsBoolean;
}
public static int GetInt32(this TypeTreeObject asset, string fieldName)
{
return asset.ReleaseFields[fieldName].AsInt32;
}
public static string GetString(this TypeTreeObject asset, string fieldName)
{
return asset.ReleaseFields[fieldName].AsString;
}
public static string? TryGetString(this TypeTreeObject asset, string fieldName)
{
return asset.ReleaseFields.TryGetField(fieldName)?.AsString;
}
public static TypeTreeObject? ResolveAsset(this TypeTreeObject asset, IPPtr pptr)
{
return asset.Collection.TryGetAsset(new PPtr<TypeTreeObject>(pptr.FileID, pptr.PathID));
}
}
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net4.8;net7.0;net8.0</TargetFrameworks>
<LangVersion>Latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="NUnit" Version="4.2.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetRipper.Mining.PredefinedAssets\AssetRipper.Mining.PredefinedAssets.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,85 @@
using System.Numerics;
using System.Text.Json;
namespace AssetRipper.Mining.PredefinedAssets.Tests;
public class Tests
{
[Test]
public void TextAssetSerializesConsistently()
{
//This test ensures that the TextAsset hash is serialized consistently on all the test target frameworks.
TextAsset asset = new TextAsset("Example", "Hello, World!"u8);
string json = asset.ToJson().Replace(Environment.NewLine, "\n");
Assert.That(json, Is.EqualTo("""
{
"$type": "TextAsset",
"Length": 13,
"Hash": 281850845012336186393611809232225740901,
"Name": "Example"
}
""".Replace(Environment.NewLine, "\n")));
}
[Test]
public void UnityPackageDataCanBeSerialized()
{
UnityPackageData package = new UnityPackageData("Example", "1.0.0", true);
package.Assets.Add(new TextAsset("", ""u8), default);
string json = package.ToJson();
Assert.That(json, Is.Not.Empty);
}
[Test]
public void UnityPackageDataCanBeDeserialized()
{
UnityPackageData package = UnityPackageData.FromJson(MakeJson());
Assert.That(package.Assets, Is.Not.Empty);
static string MakeJson()
{
UnityPackageData package = new UnityPackageData("Example", "1.0.0", true);
package.Assets.Add(new TextAsset("", ""u8), default);
return package.ToJson();
}
}
[Test]
public void Vector3Serialization()
{
string result = """
{
"X": 1,
"Y": 2,
"Z": 3
}
""".Replace("\r", null);
Vector3 vector = new Vector3(1.0f, 2.0f, 3.0f);
Assert.That(JsonSerializer.Serialize(vector, MiningSerializerContext.Default.Vector3).Replace("\r", null), Is.EqualTo(result));
}
[Test]
public void Vector3Deserialization()
{
string json = """{ "X": 1.0, "Y": 2.0, "Z": 3.0 }""";
Vector3 result = new Vector3(1.0f, 2.0f, 3.0f);
Assert.That(JsonSerializer.Deserialize(json, MiningSerializerContext.Default.Vector3), Is.EqualTo(result));
}
[TestCase("")]
[TestCase("{}")]
public void EmptyEngineResourceDataDeserialization(string json)
{
EngineResourceData result = EngineResourceData.FromJson(json);
Assert.Multiple(() =>
{
Assert.That(result.DefaultResources, Is.Not.Null);
Assert.That(result.ExtraResources, Is.Not.Null);
});
Assert.Multiple(() =>
{
Assert.That(result.DefaultResources, Is.Empty);
Assert.That(result.ExtraResources, Is.Empty);
});
}
}
@@ -0,0 +1 @@
global using NUnit.Framework;
@@ -0,0 +1,81 @@
using System.Collections;
namespace AssetRipper.Mining.PredefinedAssets;
public readonly struct AssetDictionary : IReadOnlyCollection<KeyValuePair<Object, PPtr>>, ICollection<KeyValuePair<Object, PPtr>>
{
//This class implements all the IReadOnlyDictionary`2 members, but does not implement the interface because that changes how System.Text.Json serializes it.
private readonly Dictionary<Object, PPtr> _dictionary = new();
public int Count => _dictionary.Count;
public IEnumerable<Object> Keys => _dictionary.Keys;
public IEnumerable<PPtr> Values => _dictionary.Values;
public PPtr this[Object key] => _dictionary[key];
public AssetDictionary()
{
}
public void Add(Object key, PPtr value) => _dictionary.Add(key, value);
public void Add(MonoScript key, UnityGuid guid) => Add(key, new PPtr(11500000, guid, AssetType.Meta));
public void Clear() => _dictionary.Clear();
public bool ContainsKey(Object key)
{
return _dictionary.ContainsKey(key);
}
public bool TryAdd(Object key, PPtr value)
{
#if NETSTANDARD
if (_dictionary.ContainsKey(key))
{
return false;
}
else
{
_dictionary.Add(key, value);
return true;
}
#else
return _dictionary.TryAdd(key, value);
#endif
}
public bool TryGetValue(Object key, out PPtr value)
{
return _dictionary.TryGetValue(key, out value);
}
public IEnumerator<KeyValuePair<Object, PPtr>> GetEnumerator() => _dictionary.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
bool ICollection<KeyValuePair<Object, PPtr>>.IsReadOnly => ((ICollection<KeyValuePair<Object, PPtr>>)_dictionary).IsReadOnly;
void ICollection<KeyValuePair<Object, PPtr>>.Add(KeyValuePair<Object, PPtr> item)
{
((ICollection<KeyValuePair<Object, PPtr>>)_dictionary).Add(item);
}
bool ICollection<KeyValuePair<Object, PPtr>>.Contains(KeyValuePair<Object, PPtr> item)
{
return ((ICollection<KeyValuePair<Object, PPtr>>)_dictionary).Contains(item);
}
void ICollection<KeyValuePair<Object, PPtr>>.CopyTo(KeyValuePair<Object, PPtr>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<Object, PPtr>>)_dictionary).CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<Object, PPtr>>.Remove(KeyValuePair<Object, PPtr> item)
{
return ((ICollection<KeyValuePair<Object, PPtr>>)_dictionary).Remove(item);
}
}
@@ -1,14 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net7.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>Latest</LangVersion>
<Nullable>enable</Nullable>
<IsTrimmable>true</IsTrimmable>
<IsAotCompatible>true</IsAotCompatible>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<Version>1.0.0</Version>
<Version>1.4.0</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<PackageId>AssetRipper.Mining.PredefinedAssets</PackageId>
<PackageTags>C# Unity</PackageTags>
@@ -16,7 +17,7 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<Copyright>Copyright (c) 2023 ds5678</Copyright>
<Copyright>Copyright (c) 2023 - 2024 ds5678</Copyright>
<Description>Library for storing datamined asset information.</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
@@ -25,12 +26,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AssetRipper.Primitives" Version="2.0.1" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PackageReference Include="AssetRipper.Primitives" Version="3.1.3" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.0-rc.1.23419.4" />
<PackageReference Include="PolySharp" Version="1.14.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
</Project>
@@ -0,0 +1,28 @@
namespace AssetRipper.Mining.PredefinedAssets;
public enum AssetType
{
/// <summary>
/// Used by a released game
/// </summary>
Internal = 0,
/// <summary>
/// Library asset file. It is editor created file, it doesn't exist in Assets directory
/// It has the format "library/cache/[first Hash byte as hex]/[Hash as hex]"
/// </summary>
Cached = 1,
/// <summary>
/// Serialized asset file. It contains all parameters inside itself.
/// </summary>
/// <remarks>
/// All yaml files use this type.
/// </remarks>
Serialized = 2,
/// <summary>
/// Binary asset file. It contains all parameters inside meta file.
/// </summary>
/// <remarks>
/// Any "universal" format uses this type. For example, png, jpg, tga, wav, ogg, fbx, cs, dll, shader, etc.
/// </remarks>
Meta = 3,
}
@@ -19,4 +19,16 @@ public sealed record class AudioClip : NamedObject
/// 5.0.0 to Max
/// </summary>
public required float Length { get; init; }
public AudioClip()
{
}
[SetsRequiredMembers]
public AudioClip(string name, int channels, int frequency, float length) : base(name)
{
Channels = channels;
Frequency = frequency;
Length = length;
}
}
@@ -0,0 +1,5 @@
using System.Numerics;
namespace AssetRipper.Mining.PredefinedAssets;
public record struct AxisAlignedBoundingBox(Vector3 Center, Vector3 Extent);
@@ -2,4 +2,12 @@
public sealed record class Cubemap : Texture2D
{
}
public Cubemap()
{
}
[SetsRequiredMembers]
public Cubemap(string name, int width, int height) : base(name, width, height)
{
}
}
@@ -1,16 +1,35 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetRipper.Mining.PredefinedAssets;
public readonly record struct EngineResourceData(Dictionary<long, Object> DefaultResources, Dictionary<long, Object> ExtraResources)
public readonly record struct EngineResourceData
{
public Dictionary<long, Object> DefaultResources { get; }
public Dictionary<long, Object> ExtraResources { get; }
public EngineResourceData()
{
DefaultResources = new();
ExtraResources = new();
}
[JsonConstructor]
public EngineResourceData(Dictionary<long, Object>? defaultResources, Dictionary<long, Object>? extraResources)
{
DefaultResources = defaultResources ?? new();
ExtraResources = extraResources ?? new();
}
public readonly string ToJson()
{
return JsonSerializer.Serialize(this, InternalSerializerContext.Default.EngineResourceData);
return JsonSerializer.Serialize(this, MiningSerializerContext.Default.EngineResourceData);
}
public static EngineResourceData FromJson(string text)
{
return JsonSerializer.Deserialize(text, InternalSerializerContext.Default.EngineResourceData);
return string.IsNullOrEmpty(text)
? new()
: JsonSerializer.Deserialize(text, MiningSerializerContext.Default.EngineResourceData);
}
}
@@ -6,4 +6,24 @@ public sealed record class GenericNamedObject : NamedObject
{
[JsonInclude]
public new required int TypeID { get; init; }
}
public GenericNamedObject()
{
}
[SetsRequiredMembers]
public GenericNamedObject(string name, int typeID) : base(name)
{
TypeID = typeID;
}
public static GenericNamedObject CreateComputeShader(string name)
{
return new(name, 72);
}
public static GenericNamedObject CreateFont(string name)
{
return new(name, 128);
}
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
namespace AssetRipper.Mining.PredefinedAssets;
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(EngineResourceData))]
[JsonSerializable(typeof(UnityPackageData))]
internal sealed partial class InternalSerializerContext : JsonSerializerContext
{
}
@@ -1,8 +1,16 @@
using System.Text.Json.Serialization;
namespace AssetRipper.Mining.PredefinedAssets;
namespace AssetRipper.Mining.PredefinedAssets;
public sealed record class Material : NamedObject
{
public required string? Shader { get; init; }
public Material()
{
}
[SetsRequiredMembers]
public Material(string name, string? shader) : base(name)
{
Shader = shader;
}
}
+15 -1
View File
@@ -2,5 +2,19 @@
public sealed record class Mesh : NamedObject
{
public required uint VertexCount { get; init; }
public required int VertexCount { get; init; }
public required int SubMeshCount { get; init; }
public required AxisAlignedBoundingBox LocalAABB { get; init; }
public Mesh()
{
}
[SetsRequiredMembers]
public Mesh(string name, int vertexCount, int subMeshCount, AxisAlignedBoundingBox localAabb) : base(name)
{
VertexCount = vertexCount;
SubMeshCount = subMeshCount;
LocalAABB = localAabb;
}
}
@@ -0,0 +1,11 @@
using System.Text.Json.Serialization;
namespace AssetRipper.Mining.PredefinedAssets;
[JsonSourceGenerationOptions(WriteIndented = true, IncludeFields = true)]
[JsonSerializable(typeof(EngineResourceData))]
[JsonSerializable(typeof(UnityPackageData))]
[JsonSerializable(typeof(ReferenceAssemblyData))]
public sealed partial class MiningSerializerContext : JsonSerializerContext
{
}
@@ -5,4 +5,21 @@ public sealed record class MonoScript : Object
public required string AssemblyName { get; init; }
public required string Namespace { get; init; }
public required string ClassName { get; init; }
public MonoScript()
{
}
[SetsRequiredMembers]
public MonoScript(string assemblyName, string @namespace, string className)
{
AssemblyName = assemblyName;
Namespace = @namespace;
ClassName = className;
}
public static MonoScript FromType(Type type)
{
return new MonoScript(type.Assembly.GetName().Name ?? "", type.Namespace ?? "", type.Name);
}
}
@@ -3,4 +3,14 @@
public abstract record class NamedObject : Object
{
public required string Name { get; init; }
public NamedObject()
{
}
[SetsRequiredMembers]
public NamedObject(string name)
{
Name = name;
}
}
+12 -1
View File
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetRipper.Mining.PredefinedAssets;
@@ -55,4 +56,14 @@ public abstract record class Object
_ => 0,
};
}
public string ToJson()
{
return JsonSerializer.Serialize(this, MiningSerializerContext.Default.Object);
}
public static Object? FromJson(string text)
{
return JsonSerializer.Deserialize(text, MiningSerializerContext.Default.Object);
}
}
@@ -0,0 +1,11 @@
namespace AssetRipper.Mining.PredefinedAssets;
/// <summary>
/// A data structure representing a reference to an asset.
/// </summary>
/// <param name="FileID">The local identifier within the file.</param>
/// <param name="Guid">The global identifier for the file.</param>
/// <param name="Type">The type of file. </param>
public readonly record struct PPtr(long FileID, UnityGuid Guid, AssetType Type)
{
}
@@ -0,0 +1,16 @@
using System.Text.Json;
namespace AssetRipper.Mining.PredefinedAssets;
public readonly record struct ReferenceAssemblyData(List<string> Unity, List<string>? Mono2, List<string>? Mono4, List<string>? CoreCLR)
{
public string ToJson()
{
return JsonSerializer.Serialize(this, MiningSerializerContext.Default.ReferenceAssemblyData);
}
public static ReferenceAssemblyData FromJson(string json)
{
return JsonSerializer.Deserialize<ReferenceAssemblyData>(json, MiningSerializerContext.Default.ReferenceAssemblyData);
}
}
+11 -1
View File
@@ -18,4 +18,14 @@ public sealed record class Shader : NamedObject
{
return HashCode.Combine(Name, PropertyNames.Length);
}
}
public Shader()
{
}
[SetsRequiredMembers]
public Shader(string name, string[] propertyNames) : base(name)
{
PropertyNames = propertyNames;
}
}
+11 -1
View File
@@ -3,4 +3,14 @@
public sealed record class Sprite : NamedObject
{
public required string? Texture { get; init; }
}
public Sprite()
{
}
[SetsRequiredMembers]
public Sprite(string name, string? texture) : base(name)
{
Texture = texture;
}
}
@@ -1,5 +1,4 @@
using System.Buffers.Binary;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
namespace AssetRipper.Mining.PredefinedAssets;
@@ -31,10 +30,22 @@ public sealed record class TextAsset : NamedObject
private static UInt128 HashData(ReadOnlySpan<byte> data)
{
Span<byte> buffer = stackalloc byte[16];
MD5.HashData(data, buffer);
HashData(data, buffer);
#if NET8_0_OR_GREATER
return BinaryPrimitives.ReadUInt128LittleEndian(buffer);
#else
return new UInt128(
BinaryPrimitives.ReadUInt64LittleEndian(buffer[8..]),
BinaryPrimitives.ReadUInt64LittleEndian(buffer));
//On .NET 8, replace with ReadUInt128LittleEndian
#endif
}
}
private static void HashData(ReadOnlySpan<byte> data, Span<byte> buffer)
{
#if NET5_0_OR_GREATER
MD5.HashData(data, buffer);
#else
MD5.Create().ComputeHash(data.ToArray()).AsSpan().CopyTo(buffer);
#endif
}
}
@@ -4,4 +4,15 @@ public record class Texture2D : NamedObject
{
public required int Width { get; init; }
public required int Height { get; init; }
public Texture2D()
{
}
[SetsRequiredMembers]
public Texture2D(string name, int width, int height) : base(name)
{
Width = width;
Height = height;
}
}
@@ -0,0 +1,77 @@
#if NET7_0_OR_GREATER
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(UInt128))]
#else
using AssetRipper.Mining.PredefinedAssets;
using System.Buffers;
using System.Numerics;
using System.Text;
using System.Text.Json.Serialization;
namespace System;
/// <summary>
/// A limited polyfill for the UInt128 struct.
/// </summary>
[JsonConverter(typeof(UInt128JsonConverter))]
public readonly record struct UInt128
{
private readonly ulong _lower;
private readonly ulong _upper;
/// <summary>Initializes a new instance of the <see cref="UInt128" /> struct.</summary>
/// <param name="upper">The upper 64-bits of the 128-bit value.</param>
/// <param name="lower">The lower 64-bits of the 128-bit value.</param>
public UInt128(ulong upper, ulong lower)
{
_lower = lower;
_upper = upper;
}
public override string ToString()
{
return _upper == 0 ? _lower.ToString() : ToBigInteger().ToString();
}
public static UInt128 Parse(string value)
{
return TryParse(value, out UInt128 result) ? result : throw new FormatException("Input string was not in a correct format.");
}
internal static UInt128 Parse(ReadOnlySpan<byte> value)
{
byte[] rented = ArrayPool<byte>.Shared.Rent(value.Length);
value.CopyTo(rented);
UInt128 result = Parse(Encoding.ASCII.GetString(rented, 0, value.Length));
ArrayPool<byte>.Shared.Return(rented);
return result;
}
public static bool TryParse(string value, out UInt128 result)
{
if (BigInteger.TryParse(value, out BigInteger bigInteger))
{
result = FromBigInteger(bigInteger);
return true;
}
else
{
result = default;
return false;
}
}
private BigInteger ToBigInteger()
{
return (new BigInteger(_upper) << 64) | new BigInteger(_lower);
}
private static UInt128 FromBigInteger(BigInteger value)
{
ulong upper = (ulong)(value >> 64);
ulong lower = (ulong)(value & LowerBitMask);
return new UInt128(upper, lower);
}
private static readonly BigInteger LowerBitMask = new BigInteger(ulong.MaxValue);
}
#endif
@@ -0,0 +1,19 @@
#if !NET7_0_OR_GREATER
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetRipper.Mining.PredefinedAssets;
public sealed class UInt128JsonConverter : JsonConverter<UInt128>
{
public override UInt128 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return UInt128.Parse(reader.ValueSpan);
}
public override void Write(Utf8JsonWriter writer, UInt128 value, JsonSerializerOptions options)
{
writer.WriteRawValue(value.ToString());
}
}
#endif
@@ -1,5 +1,4 @@
using AssetRipper.Primitives;
using System.Text.Json;
using System.Text.Json;
namespace AssetRipper.Mining.PredefinedAssets;
@@ -10,26 +9,32 @@ namespace AssetRipper.Mining.PredefinedAssets;
/// File extensions are not included in any names.
/// </remarks>
/// <param name="Name">The name of this Unity package.</param>
/// <param name="Version">The version of this Unity package. Only applicable if <paramref name="UsedInPackageJson"/> is true.</param>
/// <param name="Version">The version or git url of this Unity package. Only applicable if <paramref name="UsedInPackageJson"/> is true.</param>
/// <param name="UsedInPackageJson">If true, this Unity package should be referenced in the project's package json file.</param>
/// <param name="Assemblies">A dictionary of compiled dll assemblies in the package.</param>
/// <param name="Scripts">A dictionary of loose cs scripts in the package. Assembly name : { Full name : Guid }</param>
/// <param name="Assets">A dictionary of assets in the package.</param>
public readonly record struct UnityPackageData(
string Name,
Version Version,
string Version,
bool UsedInPackageJson,
Dictionary<string, UnityGuid> Assemblies,
Dictionary<string, Dictionary<string, UnityGuid>> Scripts,
KeyValuePair<Object, UnityGuid>[] Assets)
AssetDictionary Assets)
{
public UnityPackageData(string name, string version, bool usedInPackageJson) : this(name, version, usedInPackageJson, new(), new())
{
}
public UnityPackageData(string name, string version = "") : this(name, version, string.IsNullOrEmpty(version))
{
}
public readonly string ToJson()
{
return JsonSerializer.Serialize(this, InternalSerializerContext.Default.UnityPackageData);
return JsonSerializer.Serialize(this, MiningSerializerContext.Default.UnityPackageData);
}
public static UnityPackageData FromJson(string text)
{
return JsonSerializer.Deserialize(text, InternalSerializerContext.Default.UnityPackageData);
return JsonSerializer.Deserialize(text, MiningSerializerContext.Default.UnityPackageData);
}
}
}
@@ -0,0 +1,6 @@
global using System.Diagnostics.CodeAnalysis;
#if NET5_0_OR_GREATER
global using UnityGuid = AssetRipper.Primitives.UnityGuid;
#else
global using UnityGuid = string;
#endif
+42
View File
@@ -14,6 +14,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Mining.Predefin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Mining.EngineFileExtractor", "AssetRipper.Mining.EngineFileExtractor\AssetRipper.Mining.EngineFileExtractor.csproj", "{DAD9BA2F-8A03-43D8-A3E5-73493A10AF0B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Mining.PredefinedAssets.Tests", "AssetRipper.Mining.PredefinedAssets.Tests\AssetRipper.Mining.PredefinedAssets.Tests.csproj", "{C3E8E9EA-1710-4346-B96A-EA757FB13301}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Import", "..\AssetRipper\Source\AssetRipper.Import\AssetRipper.Import.csproj", "{44876B0D-F234-46E7-9A94-BE35CA29049F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.SourceGenerated.Extensions", "..\AssetRipper\Source\AssetRipper.SourceGenerated.Extensions\AssetRipper.SourceGenerated.Extensions.csproj", "{B5094214-6FC3-4F55-B448-D83E114BC1BC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Numerics", "..\AssetRipper\Source\AssetRipper.Numerics\AssetRipper.Numerics.csproj", "{BDE02D36-76D0-4A73-A30C-6CD015FA5A99}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Assets", "..\AssetRipper\Source\AssetRipper.Assets\AssetRipper.Assets.csproj", "{98EE060B-FFE4-4D52-B361-69D42D2C00A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.IO.Files", "..\AssetRipper\Source\AssetRipper.IO.Files\AssetRipper.IO.Files.csproj", "{6F14FBBA-B839-4023-8C92-138A57F30673}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.SerializationLogic", "..\AssetRipper\Source\AssetRipper.SerializationLogic\AssetRipper.SerializationLogic.csproj", "{A24296F8-A10F-43B5-8190-4406C75882D3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -28,6 +42,34 @@ Global
{DAD9BA2F-8A03-43D8-A3E5-73493A10AF0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DAD9BA2F-8A03-43D8-A3E5-73493A10AF0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DAD9BA2F-8A03-43D8-A3E5-73493A10AF0B}.Release|Any CPU.Build.0 = Release|Any CPU
{C3E8E9EA-1710-4346-B96A-EA757FB13301}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3E8E9EA-1710-4346-B96A-EA757FB13301}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3E8E9EA-1710-4346-B96A-EA757FB13301}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3E8E9EA-1710-4346-B96A-EA757FB13301}.Release|Any CPU.Build.0 = Release|Any CPU
{44876B0D-F234-46E7-9A94-BE35CA29049F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44876B0D-F234-46E7-9A94-BE35CA29049F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44876B0D-F234-46E7-9A94-BE35CA29049F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44876B0D-F234-46E7-9A94-BE35CA29049F}.Release|Any CPU.Build.0 = Release|Any CPU
{B5094214-6FC3-4F55-B448-D83E114BC1BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5094214-6FC3-4F55-B448-D83E114BC1BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5094214-6FC3-4F55-B448-D83E114BC1BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5094214-6FC3-4F55-B448-D83E114BC1BC}.Release|Any CPU.Build.0 = Release|Any CPU
{BDE02D36-76D0-4A73-A30C-6CD015FA5A99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDE02D36-76D0-4A73-A30C-6CD015FA5A99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDE02D36-76D0-4A73-A30C-6CD015FA5A99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDE02D36-76D0-4A73-A30C-6CD015FA5A99}.Release|Any CPU.Build.0 = Release|Any CPU
{98EE060B-FFE4-4D52-B361-69D42D2C00A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98EE060B-FFE4-4D52-B361-69D42D2C00A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98EE060B-FFE4-4D52-B361-69D42D2C00A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98EE060B-FFE4-4D52-B361-69D42D2C00A4}.Release|Any CPU.Build.0 = Release|Any CPU
{6F14FBBA-B839-4023-8C92-138A57F30673}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F14FBBA-B839-4023-8C92-138A57F30673}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F14FBBA-B839-4023-8C92-138A57F30673}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F14FBBA-B839-4023-8C92-138A57F30673}.Release|Any CPU.Build.0 = Release|Any CPU
{A24296F8-A10F-43B5-8190-4406C75882D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A24296F8-A10F-43B5-8190-4406C75882D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A24296F8-A10F-43B5-8190-4406C75882D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A24296F8-A10F-43B5-8190-4406C75882D3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE