mirror of
https://github.com/AssetRipper/AssetRipper.Mining.git
synced 2026-11-13 20:05:34 -10:00
Compare commits
26
Commits
1.0.2
...
assetstools
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffb82e8164 | ||
|
|
c39c2e5d34 | ||
|
|
3366a0125a | ||
|
|
fcd32bbdba | ||
|
|
98cf7b1eed | ||
|
|
58d5eaf0aa | ||
|
|
888b673dce | ||
|
|
9627dc2d8d | ||
|
|
54f41eda93 | ||
|
|
8df013ebed | ||
|
|
9047c383bb | ||
|
|
bd12d9eae3 | ||
|
|
87328aaac2 | ||
|
|
9ca9112942 | ||
|
|
8e0f803787 | ||
|
|
f01470f867 | ||
|
|
ab8b136b19 | ||
|
|
e9b0003601 | ||
|
|
9e2097dd81 | ||
|
|
63316d5977 | ||
|
|
0bfce878cb | ||
|
|
8c56291f96 | ||
|
|
5798136567 | ||
|
|
18b456e6b8 | ||
|
|
d077b228d6 | ||
|
|
c34f7447b8 |
No files matched your search
+258
@@ -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
|
||||
@@ -0,0 +1,270 @@
|
||||
using AngleSharp;
|
||||
using AngleSharp.Dom;
|
||||
using AssetRipper.Primitives;
|
||||
using System.Diagnostics;
|
||||
using System.Formats.Tar;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace AssetRipper.Mining.AssemblyNameCollector;
|
||||
|
||||
public readonly record struct AssemblyData(IReadOnlyList<string> Mono2, IReadOnlyList<string> Mono4, IReadOnlyList<string> Unity, IReadOnlyList<KeyValuePair<string, UnityGuid>> UnityExtensions)
|
||||
{
|
||||
public static AssemblyData FromFolder(string root)
|
||||
{
|
||||
IReadOnlyList<string> mono2 = GetAssemblies_Mono2(root);
|
||||
IReadOnlyList<string> mono4 = GetAssemblies_Mono4(root);
|
||||
IReadOnlyList<string> unity = GetAssemblies_Unity(root);
|
||||
IReadOnlyList<KeyValuePair<string, UnityGuid>> unityExtensions = GetUnityExtensions(root).Concat(GetUnityPackages(root)).OrderBy(pair => pair.Key).ToList();
|
||||
return new AssemblyData(mono2, mono4, unity, unityExtensions);
|
||||
}
|
||||
|
||||
public bool Equals(AssemblyData other)
|
||||
{
|
||||
return Mono2.SequenceEqual(other.Mono2) && Mono4.SequenceEqual(other.Mono4) && Unity.SequenceEqual(other.Unity) && UnityExtensions.SequenceEqual(other.UnityExtensions);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
HashCode hash = new();
|
||||
foreach (string assembly in Mono2)
|
||||
{
|
||||
hash.Add(assembly);
|
||||
}
|
||||
foreach (string assembly in Mono4)
|
||||
{
|
||||
hash.Add(assembly);
|
||||
}
|
||||
foreach (string assembly in Unity)
|
||||
{
|
||||
hash.Add(assembly);
|
||||
}
|
||||
foreach (KeyValuePair<string, UnityGuid> pair in UnityExtensions)
|
||||
{
|
||||
hash.Add(pair);
|
||||
}
|
||||
return hash.ToHashCode();
|
||||
}
|
||||
|
||||
static IReadOnlyList<string> GetAssemblies_Mono2(string root)
|
||||
{
|
||||
return GetAssemblies(root,
|
||||
"Editor/Data/Mono/lib/mono/unity",
|
||||
"Editor/Data/Mono/lib/mono/2.0",
|
||||
"Editor/Data/Frameworks/Mono.framework");
|
||||
}
|
||||
|
||||
static IReadOnlyList<string> GetAssemblies_Mono4(string root)
|
||||
{
|
||||
return GetAssemblies(root,
|
||||
"Editor/Data/MonoBleedingEdge/lib/mono/unityjit-win32",
|
||||
"Editor/Data/MonoBleedingEdge/lib/mono/unityjit",
|
||||
"Editor/Data/MonoBleedingEdge/lib/mono/unity",
|
||||
"Editor/Data/MonoBleedingEdge/lib/mono/4.5",
|
||||
"Editor/Data/MonoBleedingEdge/lib/mono/4.0");
|
||||
}
|
||||
|
||||
static IReadOnlyList<string> GetAssemblies_Unity(string root)
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(root, "Editor/Data/Frameworks")))
|
||||
{
|
||||
// Unity 2
|
||||
return ["UnityEngine"];
|
||||
}
|
||||
|
||||
return GetAssemblies(root,
|
||||
"Editor/Data/PlaybackEngines/windowsstandalonesupport/Variations/win64_nondevelopment/Data/Managed",
|
||||
"Editor/Data/PlaybackEngines/windowsstandalonesupport/Variations/win64_nondevelopment_mono/Data/Managed",
|
||||
"Editor/Data/PlaybackEngines/windowsstandalonesupport/Variations/win64_player_nondevelopment_mono/Data/Managed",
|
||||
"Editor/Data/PlaybackEngines/windows64standaloneplayer/Managed",
|
||||
"Editor/Data/PlaybackEngines/windowsstandaloneplayer/Managed");
|
||||
}
|
||||
|
||||
static IReadOnlyList<string> GetAssemblies(string root, params ReadOnlySpan<string> relativePaths)
|
||||
{
|
||||
foreach (string relativePath in relativePaths)
|
||||
{
|
||||
string path = Path.Combine(root, relativePath);
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
List<string> result = GetManagedAssemblies(path).ToList();
|
||||
string facadeDirectory = Path.Combine(path, "Facades");
|
||||
if (Directory.Exists(facadeDirectory))
|
||||
{
|
||||
result.AddRange(GetManagedAssemblies(facadeDirectory).Where(a => !result.Contains(a)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
static IEnumerable<string> GetManagedAssemblies(string directory)
|
||||
{
|
||||
return Directory.EnumerateFiles(directory, "*.dll", SearchOption.AllDirectories)
|
||||
.Select(Path.GetFileNameWithoutExtension)
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.Distinct()
|
||||
.Order()!;
|
||||
}
|
||||
|
||||
static IReadOnlyList<KeyValuePair<string, UnityGuid>> GetUnityExtensions(string root)
|
||||
{
|
||||
string directory = Path.Combine(root, "Editor/Data/UnityExtensions");
|
||||
if (Directory.Exists(directory))
|
||||
{
|
||||
List<(string, UnityGuid)> extractedArtifacts = new();
|
||||
foreach (string file in Directory.EnumerateFiles(directory, "ivy.xml", SearchOption.AllDirectories))
|
||||
{
|
||||
string xml = File.ReadAllText(file);
|
||||
IDocument document = BrowsingContext.New(Configuration.Default.WithXml()).OpenAsync(req => req.Content(xml)).GetAwaiter().GetResult();
|
||||
|
||||
foreach (IElement artifact in document.QuerySelectorAll("artifact"))
|
||||
{
|
||||
string? name = artifact.GetAttribute("name");
|
||||
string? type = artifact.GetAttribute("type");
|
||||
string? ext = artifact.GetAttribute("ext");
|
||||
string? guidString = artifact.GetAttribute("e:guid"); // namespaced attribute
|
||||
|
||||
if (string.IsNullOrEmpty(name) || type is not "dll" || ext is not "dll" || string.IsNullOrEmpty(guidString) || !TryParseGuid(guidString, out UnityGuid guid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
extractedArtifacts.Add((name, guid));
|
||||
}
|
||||
}
|
||||
Dictionary<string, List<(string, UnityGuid)>> dictionary = new();
|
||||
foreach ((string path, UnityGuid guid) in extractedArtifacts)
|
||||
{
|
||||
string name = Path.GetFileName(path);
|
||||
if (!dictionary.TryGetValue(name, out List<(string, UnityGuid)>? newList))
|
||||
{
|
||||
newList = new();
|
||||
dictionary.Add(name, newList);
|
||||
}
|
||||
newList.Add((path, guid));
|
||||
}
|
||||
List<KeyValuePair<string, UnityGuid>> finalList = new();
|
||||
foreach ((string name, List<(string, UnityGuid)> subList) in dictionary.OrderBy(p => p.Key))
|
||||
{
|
||||
Debug.Assert(subList.Count > 0);
|
||||
UnityGuid guid;
|
||||
if (subList.Count == 1)
|
||||
{
|
||||
guid = subList[0].Item2;
|
||||
}
|
||||
else
|
||||
{
|
||||
guid = subList.FirstOrDefault(pair => pair.Item1 == name).Item2;
|
||||
if (guid != default)
|
||||
{
|
||||
goto Found;
|
||||
}
|
||||
|
||||
ReadOnlySpan<string> starts =
|
||||
[
|
||||
"Standalone/", // Preferred over Editor/
|
||||
"Runtime/", // Preferred over RuntimeEditor/
|
||||
|
||||
// NUnit
|
||||
"portable/",
|
||||
"nunit-standalone/",
|
||||
];
|
||||
foreach (string start in starts)
|
||||
{
|
||||
foreach ((string path, UnityGuid subGuid) in subList)
|
||||
{
|
||||
if (path.StartsWith(start, StringComparison.Ordinal))
|
||||
{
|
||||
guid = subGuid;
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException($"Failed to find a guid for {name}");
|
||||
}
|
||||
Found:
|
||||
finalList.Add(new(name, guid));
|
||||
}
|
||||
return finalList;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
static IReadOnlyList<KeyValuePair<string, UnityGuid>> GetUnityPackages(string root)
|
||||
{
|
||||
// Unity 2017.2 introduced packages, which are stored in a compressed format.
|
||||
|
||||
if (root.EndsWith("2017.4.34f1", StringComparison.Ordinal))
|
||||
{
|
||||
// Unity 2017.4.34f1 uses a weird compression format for packages.
|
||||
// It's the only version that does this, so we redirect to the subsequent version.
|
||||
return GetUnityPackages(Path.Combine(Path.GetDirectoryName(root) ?? string.Empty, "2017.4.35f1"));
|
||||
}
|
||||
else if (!Path.GetFileName(root).StartsWith("2017.", StringComparison.Ordinal))
|
||||
{
|
||||
// Unity 2018.1 introduced the Package Manager UI, which makes package references no longer automatic.
|
||||
return [];
|
||||
}
|
||||
|
||||
string directory = Path.Combine(root, "Editor/Data/Resources/PackageManager/Editor");
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
List<KeyValuePair<string, UnityGuid>> assemblyGuids = [];
|
||||
|
||||
foreach (string file in Directory.EnumerateFiles(directory, "*.tgz"))
|
||||
{
|
||||
using FileStream fileStream = File.OpenRead(file);
|
||||
using GZipStream gzipStream = new(fileStream, CompressionMode.Decompress);
|
||||
|
||||
MemoryStream tarStream = new();
|
||||
gzipStream.CopyTo(tarStream);
|
||||
tarStream.Position = 0;
|
||||
|
||||
using TarReader reader = new(tarStream);
|
||||
TarEntry? entry;
|
||||
while ((entry = reader.GetNextEntry()) is not null)
|
||||
{
|
||||
string? entryPath = entry.Name;
|
||||
if (string.IsNullOrEmpty(entryPath) || !entryPath.EndsWith(".dll.meta", StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string assemblyName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(entryPath)); // Remove .meta and .dll
|
||||
|
||||
string text = new StreamReader(entry.DataStream!).ReadToEnd();
|
||||
|
||||
string? guidString = text.Split('\n')
|
||||
.FirstOrDefault(line => line.StartsWith("guid: ", StringComparison.Ordinal))?
|
||||
.Substring("guid: ".Length)
|
||||
.Trim();
|
||||
|
||||
if (!string.IsNullOrEmpty(guidString) && TryParseGuid(guidString, out UnityGuid guid))
|
||||
{
|
||||
assemblyGuids.Add(new KeyValuePair<string, UnityGuid>(assemblyName, guid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return assemblyGuids;
|
||||
}
|
||||
|
||||
private static bool TryParseGuid(string guidString, out UnityGuid guid)
|
||||
{
|
||||
// Todo: implement a proper solution upstream
|
||||
try
|
||||
{
|
||||
guid = UnityGuid.Parse(guidString);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
guid = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using AssetRipper.Primitives;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AssetRipper.Mining.AssemblyNameCollector;
|
||||
|
||||
public readonly record struct AssemblyDataFile(IReadOnlyList<UnityVersion> Versions, IReadOnlyList<KeyValuePair<UnityVersion, AssemblyData>> Assemblies)
|
||||
{
|
||||
public void Write(string path)
|
||||
{
|
||||
using FileStream stream = File.Create(path);
|
||||
JsonSerializer.Serialize(stream, this, AssemblyDataSerializerContext.Default.AssemblyDataFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using AssetRipper.Primitives;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetRipper.Mining.AssemblyNameCollector;
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, IndentCharacter = '\t', IndentSize = 1, NewLine = "\n")]
|
||||
[JsonSerializable(typeof(AssemblyDataFile))]
|
||||
internal sealed partial class AssemblyDataSerializerContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp" Version="1.3.0" />
|
||||
<PackageReference Include="AngleSharp.Xml" Version="1.0.0" />
|
||||
<PackageReference Include="AssetRipper.Primitives" Version="3.1.6" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,35 @@
|
||||
using AssetRipper.Primitives;
|
||||
|
||||
namespace AssetRipper.Mining.AssemblyNameCollector;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Extract data
|
||||
List<UnityVersion> versions = new();
|
||||
List<KeyValuePair<UnityVersion, AssemblyData>> list = new();
|
||||
foreach ((string directory, UnityVersion version) in GetRootDirectoriesInOrder(args[0]))
|
||||
{
|
||||
Console.WriteLine(directory);
|
||||
versions.Add(version);
|
||||
AssemblyData data = AssemblyData.FromFolder(directory);
|
||||
if (list.Count is 0 || !list[^1].Value.Equals(data))
|
||||
{
|
||||
list.Add(new(version, data));
|
||||
}
|
||||
}
|
||||
|
||||
// Write data
|
||||
new AssemblyDataFile(versions, list).Write(args[1]);
|
||||
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
static IEnumerable<(string, UnityVersion)> GetRootDirectoriesInOrder(string parentDirectory)
|
||||
{
|
||||
return Directory.EnumerateDirectories(parentDirectory)
|
||||
.Select(d => (d, UnityVersion.Parse(Path.GetFileName(d))))
|
||||
.OrderBy(p => p.Item2);
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,18 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AssetsTools.NET" Version="3.0.0-preview3" />
|
||||
<PackageReference Include="AssetsTools.NET" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetRipper.Mining.PredefinedAssets\AssetRipper.Mining.PredefinedAssets.csproj" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetRipper.Mining.PredefinedAssets\AssetRipper.Mining.PredefinedAssets.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +1,6 @@
|
||||
using AssetsTools.NET;
|
||||
using AssetRipper.Mining.PredefinedAssets;
|
||||
using AssetsTools.NET;
|
||||
using System.Numerics;
|
||||
|
||||
namespace AssetRipper.Mining.EngineFileExtractor;
|
||||
|
||||
@@ -9,4 +11,14 @@ internal static class AssetTypeValueFieldExtensions
|
||||
AssetTypeValueField result = @this.Get(name);
|
||||
return result.IsDummy ? null : result;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector3 AsVector3(this AssetTypeValueField @this)
|
||||
{
|
||||
return new Vector3(@this["x"].AsFloat, @this["y"].AsFloat, @this["z"].AsFloat);
|
||||
}
|
||||
|
||||
public static AxisAlignedBoundingBox AsAxisAlignedBoundingBox(this AssetTypeValueField @this)
|
||||
{
|
||||
return new AxisAlignedBoundingBox(@this["m_Center"].AsVector3(), @this["m_Extent"].AsVector3());
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,9 @@ internal static class Program
|
||||
obj = new Mesh()
|
||||
{
|
||||
Name = asset.Name,
|
||||
VertexCount = asset.BaseField.Get("m_VertexData").Get("m_VertexCount").AsUInt
|
||||
VertexCount = asset.BaseField.Get("m_VertexData").Get("m_VertexCount").AsInt,
|
||||
SubMeshCount = asset.BaseField.Get("m_SubMeshes").Get("Array").Children.Count,
|
||||
LocalAABB = asset.BaseField.Get("m_LocalAABB").AsAxisAlignedBoundingBox(),
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
+9
-6
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net5.0;net7.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net4.8;net9.0</TargetFrameworks>
|
||||
<LangVersion>Latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -11,14 +11,17 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="NUnit" Version="3.14.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.9.0">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
|
||||
<PackageReference Include="NUnit" Version="4.3.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.7.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
using System.Numerics;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AssetRipper.Mining.PredefinedAssets.Tests;
|
||||
|
||||
public class Tests
|
||||
@@ -17,4 +20,66 @@ public class Tests
|
||||
}
|
||||
""".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,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,41 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>Latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsTrimmable>true</IsTrimmable>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<Authors>ds5678</Authors>
|
||||
<Company>AssetRipper</Company>
|
||||
<Version>1.0.2</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<PackageId>AssetRipper.Mining.PredefinedAssets</PackageId>
|
||||
<PackageTags>C# Unity</PackageTags>
|
||||
<RepositoryUrl>https://github.com/AssetRipper/AssetRipper.Mining</RepositoryUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
|
||||
<Copyright>Copyright (c) 2023 - 2024 ds5678</Copyright>
|
||||
<Description>Library for storing datamined asset information.</Description>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AssetRipper.Primitives" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<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.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>Latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
<Authors>ds5678</Authors>
|
||||
<Company>AssetRipper</Company>
|
||||
<Version>1.5.0</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<PackageId>AssetRipper.Mining.PredefinedAssets</PackageId>
|
||||
<PackageTags>C# Unity</PackageTags>
|
||||
<RepositoryUrl>https://github.com/AssetRipper/AssetRipper.Mining</RepositoryUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
|
||||
<Copyright>Copyright (c) 2023 - 2025 ds5678</Copyright>
|
||||
<Description>Library for storing datamined asset information.</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AssetRipper.Primitives" Version="3.1.6" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="PolySharp" Version="1.15.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace AssetRipper.Mining.PredefinedAssets;
|
||||
namespace AssetRipper.Mining.PredefinedAssets;
|
||||
|
||||
public sealed record class GameObject : Object
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -59,11 +59,11 @@ public abstract record class Object
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return JsonSerializer.Serialize(this, InternalSerializerContext.Default.Object);
|
||||
return JsonSerializer.Serialize(this, MiningSerializerContext.Default.Object);
|
||||
}
|
||||
|
||||
public static Object? FromJson(string text)
|
||||
{
|
||||
return JsonSerializer.Deserialize(text, InternalSerializerContext.Default.Object);
|
||||
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 @@
|
||||
# AssetRipper.Mining.PredefinedAssets
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace AssetRipper.Mining.PredefinedAssets;
|
||||
namespace AssetRipper.Mining.PredefinedAssets;
|
||||
|
||||
public sealed record class Shader : NamedObject
|
||||
{
|
||||
@@ -18,4 +16,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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@
|
||||
[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;
|
||||
@@ -35,6 +37,15 @@ public readonly record struct UInt128
|
||||
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))
|
||||
@@ -57,8 +68,10 @@ public readonly record struct UInt128
|
||||
private static UInt128 FromBigInteger(BigInteger value)
|
||||
{
|
||||
ulong upper = (ulong)(value >> 64);
|
||||
ulong lower = (ulong)value;
|
||||
ulong lower = (ulong)(value & LowerBitMask);
|
||||
return new UInt128(upper, lower);
|
||||
}
|
||||
|
||||
private static readonly BigInteger LowerBitMask = new BigInteger(ulong.MaxValue);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@ public sealed class UInt128JsonConverter : JsonConverter<UInt128>
|
||||
{
|
||||
public override UInt128 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return UInt128.Parse(reader.GetString() ?? throw new JsonException("String was read as null"));
|
||||
return UInt128.Parse(reader.ValueSpan);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, UInt128 value, JsonSerializerOptions options)
|
||||
@@ -16,4 +16,4 @@ public sealed class UInt128JsonConverter : JsonConverter<UInt128>
|
||||
writer.WriteRawValue(value.ToString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,5 +1,4 @@
|
||||
using AssetRipper.Primitives;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AssetRipper.Mining.PredefinedAssets;
|
||||
|
||||
@@ -13,23 +12,29 @@ namespace AssetRipper.Mining.PredefinedAssets;
|
||||
/// <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,
|
||||
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
|
||||
@@ -16,6 +16,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Mining.EngineFi
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.Mining.PredefinedAssets.Tests", "AssetRipper.Mining.PredefinedAssets.Tests\AssetRipper.Mining.PredefinedAssets.Tests.csproj", "{C3E8E9EA-1710-4346-B96A-EA757FB13301}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.Mining.AssemblyNameCollector", "AssetRipper.Mining.AssemblyNameCollector\AssetRipper.Mining.AssemblyNameCollector.csproj", "{90716FE5-A36D-4F2F-AC14-877BF63053E2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -34,6 +36,10 @@ Global
|
||||
{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
|
||||
{90716FE5-A36D-4F2F-AC14-877BF63053E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{90716FE5-A36D-4F2F-AC14-877BF63053E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{90716FE5-A36D-4F2F-AC14-877BF63053E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90716FE5-A36D-4F2F-AC14-877BF63053E2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in new issue
Block a user