diff --git a/.editorconfig b/.editorconfig
index f0328fd7..e283b2a2 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,356 +1,27 @@
-# Standard properties
-charset = utf-8
-end_of_line = lf
-insert_final_newline = true
-csharp_indent_labels = one_less_than_current
-csharp_prefer_simple_using_statement = true:suggestion
-csharp_prefer_braces = true:silent
-csharp_style_prefer_method_group_conversion = true:silent
-csharp_style_expression_bodied_methods = false:silent
-csharp_style_expression_bodied_constructors = false:silent
-csharp_style_expression_bodied_operators = false:silent
-csharp_style_expression_bodied_properties = true:silent
-csharp_style_expression_bodied_indexers = true:silent
-csharp_style_expression_bodied_accessors = true:silent
-csharp_style_expression_bodied_lambdas = true:silent
-csharp_style_expression_bodied_local_functions = false:silent
-csharp_style_throw_expression = true:suggestion
-csharp_style_prefer_null_check_over_type_check = true:suggestion
-csharp_prefer_simple_default_expression = true:suggestion
-csharp_style_prefer_local_over_anonymous_function = true:suggestion
-csharp_style_prefer_index_operator = true:suggestion
-csharp_style_prefer_range_operator = true:suggestion
-csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
-csharp_style_prefer_tuple_swap = true:suggestion
-csharp_style_inlined_variable_declaration = true:suggestion
-csharp_style_prefer_top_level_statements = true:silent
[*]
+charset=utf-8
+end_of_line=lf
+trim_trailing_whitespace=true
+insert_final_newline=false
+indent_style=space
+indent_size=4
+
# Microsoft .NET properties
-csharp_indent_braces=false
-csharp_indent_switch_labels=true
-csharp_new_line_before_catch=true
-csharp_new_line_before_else=true
-csharp_new_line_before_finally=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
+csharp_new_line_before_members_in_object_initializers=false
csharp_preferred_modifier_order=public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
-csharp_preserve_single_line_blocks=true
+csharp_prefer_braces=true:none
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_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
-csharp_style_namespace_declarations= file_scoped:suggestion
+csharp_space_after_keywords_in_control_flow_statements=false
+csharp_space_between_method_call_parameter_list_parentheses=true
+csharp_space_between_method_declaration_parameter_list_parentheses=true
+csharp_space_between_parentheses=control_flow_statements,expressions,type_casts
csharp_style_var_elsewhere=true:suggestion
csharp_style_var_for_built_in_types=true:suggestion
csharp_style_var_when_type_is_apparent=true:suggestion
-csharp_using_directive_placement= outside_namespace:silent
-dotnet_diagnostic.bc40000.severity=warning
-dotnet_diagnostic.bc400005.severity=warning
-dotnet_diagnostic.bc40008.severity=warning
-dotnet_diagnostic.bc40056.severity=warning
-dotnet_diagnostic.bc42016.severity=warning
-dotnet_diagnostic.bc42024.severity=warning
-dotnet_diagnostic.bc42025.severity=warning
-dotnet_diagnostic.bc42104.severity=warning
-dotnet_diagnostic.bc42105.severity=warning
-dotnet_diagnostic.bc42106.severity=warning
-dotnet_diagnostic.bc42107.severity=warning
-dotnet_diagnostic.bc42304.severity=warning
-dotnet_diagnostic.bc42309.severity=warning
-dotnet_diagnostic.bc42322.severity=warning
-dotnet_diagnostic.bc42349.severity=warning
-dotnet_diagnostic.bc42353.severity=warning
-dotnet_diagnostic.bc42354.severity=warning
-dotnet_diagnostic.bc42355.severity=warning
-dotnet_diagnostic.bc42356.severity=warning
-dotnet_diagnostic.bc42358.severity=warning
-dotnet_diagnostic.bc42504.severity=warning
-dotnet_diagnostic.bc42505.severity=warning
-dotnet_diagnostic.cs0067.severity=warning
-dotnet_diagnostic.cs0078.severity=warning
-dotnet_diagnostic.cs0108.severity=warning
-dotnet_diagnostic.cs0109.severity=warning
-dotnet_diagnostic.cs0114.severity=warning
-dotnet_diagnostic.cs0162.severity=warning
-dotnet_diagnostic.cs0164.severity=warning
-dotnet_diagnostic.cs0168.severity=warning
-dotnet_diagnostic.cs0169.severity=warning
-dotnet_diagnostic.cs0183.severity=warning
-dotnet_diagnostic.cs0184.severity=warning
-dotnet_diagnostic.cs0197.severity=warning
-dotnet_diagnostic.cs0219.severity=warning
-dotnet_diagnostic.cs0252.severity=warning
-dotnet_diagnostic.cs0253.severity=warning
-dotnet_diagnostic.cs0414.severity=warning
-dotnet_diagnostic.cs0420.severity=warning
-dotnet_diagnostic.cs0465.severity=warning
-dotnet_diagnostic.cs0469.severity=warning
-dotnet_diagnostic.cs0612.severity=warning
-dotnet_diagnostic.cs0618.severity=warning
-dotnet_diagnostic.cs0628.severity=warning
-dotnet_diagnostic.cs0642.severity=warning
-dotnet_diagnostic.cs0649.severity=warning
-dotnet_diagnostic.cs0652.severity=warning
-dotnet_diagnostic.cs0657.severity=warning
-dotnet_diagnostic.cs0658.severity=warning
-dotnet_diagnostic.cs0659.severity=warning
-dotnet_diagnostic.cs0660.severity=warning
-dotnet_diagnostic.cs0661.severity=warning
-dotnet_diagnostic.cs0665.severity=warning
-dotnet_diagnostic.cs0672.severity=warning
-dotnet_diagnostic.cs0675.severity=warning
-dotnet_diagnostic.cs0693.severity=warning
-dotnet_diagnostic.cs1030.severity=warning
-dotnet_diagnostic.cs1058.severity=warning
-dotnet_diagnostic.cs1066.severity=warning
-dotnet_diagnostic.cs1522.severity=warning
-dotnet_diagnostic.cs1570.severity=warning
-dotnet_diagnostic.cs1571.severity=warning
-dotnet_diagnostic.cs1572.severity=warning
-dotnet_diagnostic.cs1573.severity=warning
-dotnet_diagnostic.cs1574.severity=warning
-dotnet_diagnostic.cs1580.severity=warning
-dotnet_diagnostic.cs1581.severity=warning
-dotnet_diagnostic.cs1584.severity=warning
-dotnet_diagnostic.cs1587.severity=warning
-dotnet_diagnostic.cs1589.severity=warning
-dotnet_diagnostic.cs1590.severity=warning
-dotnet_diagnostic.cs1591.severity=warning
-dotnet_diagnostic.cs1592.severity=warning
-dotnet_diagnostic.cs1710.severity=warning
-dotnet_diagnostic.cs1711.severity=warning
-dotnet_diagnostic.cs1712.severity=warning
-dotnet_diagnostic.cs1717.severity=warning
-dotnet_diagnostic.cs1723.severity=warning
-dotnet_diagnostic.cs1911.severity=warning
-dotnet_diagnostic.cs1957.severity=warning
-dotnet_diagnostic.cs1981.severity=warning
-dotnet_diagnostic.cs1998.severity=warning
-dotnet_diagnostic.cs4014.severity=warning
-dotnet_diagnostic.cs7022.severity=warning
-dotnet_diagnostic.cs7023.severity=warning
-dotnet_diagnostic.cs7095.severity=warning
-dotnet_diagnostic.cs8094.severity=warning
-dotnet_diagnostic.cs8123.severity=warning
-dotnet_diagnostic.cs8321.severity=warning
-dotnet_diagnostic.cs8383.severity=warning
-dotnet_diagnostic.cs8416.severity=warning
-dotnet_diagnostic.cs8417.severity=warning
-dotnet_diagnostic.cs8424.severity=warning
-dotnet_diagnostic.cs8425.severity=warning
-dotnet_diagnostic.cs8509.severity=warning
-dotnet_diagnostic.cs8524.severity=warning
-dotnet_diagnostic.cs8597.severity=warning
-dotnet_diagnostic.cs8600.severity=warning
-dotnet_diagnostic.cs8601.severity=warning
-dotnet_diagnostic.cs8602.severity=warning
-dotnet_diagnostic.cs8603.severity=warning
-dotnet_diagnostic.cs8604.severity=warning
-dotnet_diagnostic.cs8605.severity=warning
-dotnet_diagnostic.cs8607.severity=warning
-dotnet_diagnostic.cs8608.severity=warning
-dotnet_diagnostic.cs8609.severity=warning
-dotnet_diagnostic.cs8610.severity=warning
-dotnet_diagnostic.cs8611.severity=warning
-dotnet_diagnostic.cs8612.severity=warning
-dotnet_diagnostic.cs8613.severity=warning
-dotnet_diagnostic.cs8614.severity=warning
-dotnet_diagnostic.cs8615.severity=warning
-dotnet_diagnostic.cs8616.severity=warning
-dotnet_diagnostic.cs8617.severity=warning
-dotnet_diagnostic.cs8618.severity=warning
-dotnet_diagnostic.cs8619.severity=warning
-dotnet_diagnostic.cs8620.severity=warning
-dotnet_diagnostic.cs8621.severity=warning
-dotnet_diagnostic.cs8622.severity=warning
-dotnet_diagnostic.cs8624.severity=warning
-dotnet_diagnostic.cs8625.severity=warning
-dotnet_diagnostic.cs8629.severity=warning
-dotnet_diagnostic.cs8631.severity=warning
-dotnet_diagnostic.cs8632.severity=none
-dotnet_diagnostic.cs8633.severity=warning
-dotnet_diagnostic.cs8634.severity=warning
-dotnet_diagnostic.cs8643.severity=warning
-dotnet_diagnostic.cs8644.severity=warning
-dotnet_diagnostic.cs8645.severity=warning
-dotnet_diagnostic.cs8655.severity=warning
-dotnet_diagnostic.cs8656.severity=warning
-dotnet_diagnostic.cs8667.severity=warning
-dotnet_diagnostic.cs8669.severity=none
-dotnet_diagnostic.cs8670.severity=warning
-dotnet_diagnostic.cs8714.severity=warning
-dotnet_diagnostic.cs8762.severity=warning
-dotnet_diagnostic.cs8763.severity=warning
-dotnet_diagnostic.cs8764.severity=warning
-dotnet_diagnostic.cs8765.severity=warning
-dotnet_diagnostic.cs8766.severity=warning
-dotnet_diagnostic.cs8767.severity=warning
-dotnet_diagnostic.cs8768.severity=warning
-dotnet_diagnostic.cs8769.severity=warning
-dotnet_diagnostic.cs8770.severity=warning
-dotnet_diagnostic.cs8774.severity=warning
-dotnet_diagnostic.cs8775.severity=warning
-dotnet_diagnostic.cs8776.severity=warning
-dotnet_diagnostic.cs8777.severity=warning
-dotnet_diagnostic.cs8794.severity=warning
-dotnet_diagnostic.cs8819.severity=warning
-dotnet_diagnostic.cs8824.severity=warning
-dotnet_diagnostic.cs8825.severity=warning
-dotnet_diagnostic.cs8846.severity=warning
-dotnet_diagnostic.cs8847.severity=warning
-dotnet_diagnostic.cs8851.severity=warning
-dotnet_diagnostic.cs8860.severity=warning
-dotnet_diagnostic.cs8892.severity=warning
-dotnet_diagnostic.cs8907.severity=warning
-dotnet_diagnostic.cs8947.severity=warning
-dotnet_diagnostic.cs8960.severity=warning
-dotnet_diagnostic.cs8961.severity=warning
-dotnet_diagnostic.cs8962.severity=warning
-dotnet_diagnostic.cs8963.severity=warning
-dotnet_diagnostic.cs8965.severity=warning
-dotnet_diagnostic.cs8966.severity=warning
-dotnet_diagnostic.cs8971.severity=warning
-dotnet_diagnostic.wme006.severity=warning
-dotnet_naming_rule.constants_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.constants_rule.severity = warning
-dotnet_naming_rule.constants_rule.style = upper_camel_case_style
-dotnet_naming_rule.constants_rule.symbols=constants_symbols
-dotnet_naming_rule.event_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.event_rule.severity = warning
-dotnet_naming_rule.event_rule.style = upper_camel_case_style
-dotnet_naming_rule.event_rule.symbols=event_symbols
-dotnet_naming_rule.interfaces_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.interfaces_rule.severity = warning
-dotnet_naming_rule.interfaces_rule.style = i_upper_camel_case_style
-dotnet_naming_rule.interfaces_rule.symbols=interfaces_symbols
-dotnet_naming_rule.locals_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.locals_rule.severity = warning
-dotnet_naming_rule.locals_rule.style = lower_camel_case_style_1
-dotnet_naming_rule.locals_rule.symbols=locals_symbols
-dotnet_naming_rule.local_constants_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.local_constants_rule.severity = warning
-dotnet_naming_rule.local_constants_rule.style = lower_camel_case_style_1
-dotnet_naming_rule.local_constants_rule.symbols=local_constants_symbols
-dotnet_naming_rule.local_functions_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.local_functions_rule.severity = warning
-dotnet_naming_rule.local_functions_rule.style = upper_camel_case_style
-dotnet_naming_rule.local_functions_rule.symbols=local_functions_symbols
-dotnet_naming_rule.method_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.method_rule.severity = warning
-dotnet_naming_rule.method_rule.style = upper_camel_case_style
-dotnet_naming_rule.method_rule.symbols=method_symbols
-dotnet_naming_rule.parameters_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.parameters_rule.severity = warning
-dotnet_naming_rule.parameters_rule.style = lower_camel_case_style_1
-dotnet_naming_rule.parameters_rule.symbols=parameters_symbols
-dotnet_naming_rule.private_constants_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.private_constants_rule.severity = warning
-dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style
-dotnet_naming_rule.private_constants_rule.symbols=private_constants_symbols
-dotnet_naming_rule.private_instance_fields_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.private_instance_fields_rule.severity = warning
-dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
-dotnet_naming_rule.private_instance_fields_rule.symbols=private_instance_fields_symbols
-dotnet_naming_rule.private_static_fields_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.private_static_fields_rule.severity = warning
-dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style
-dotnet_naming_rule.private_static_fields_rule.symbols=private_static_fields_symbols
-dotnet_naming_rule.private_static_readonly_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.private_static_readonly_rule.severity = warning
-dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
-dotnet_naming_rule.private_static_readonly_rule.symbols=private_static_readonly_symbols
-dotnet_naming_rule.property_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.property_rule.severity = warning
-dotnet_naming_rule.property_rule.style = upper_camel_case_style
-dotnet_naming_rule.property_rule.symbols=property_symbols
-dotnet_naming_rule.public_fields_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.public_fields_rule.severity = warning
-dotnet_naming_rule.public_fields_rule.style = upper_camel_case_style
-dotnet_naming_rule.public_fields_rule.symbols=public_fields_symbols
-dotnet_naming_rule.static_readonly_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.static_readonly_rule.severity = warning
-dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style
-dotnet_naming_rule.static_readonly_rule.symbols=static_readonly_symbols
-dotnet_naming_rule.types_and_namespaces_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.types_and_namespaces_rule.severity = warning
-dotnet_naming_rule.types_and_namespaces_rule.style = upper_camel_case_style
-dotnet_naming_rule.types_and_namespaces_rule.symbols=types_and_namespaces_symbols
-dotnet_naming_rule.type_parameters_rule.import_to_resharper=as_predefined
-dotnet_naming_rule.type_parameters_rule.severity = warning
-dotnet_naming_rule.type_parameters_rule.style = t_upper_camel_case_style
-dotnet_naming_rule.type_parameters_rule.symbols=type_parameters_symbols
-dotnet_naming_style.i_upper_camel_case_style.capitalization=pascal_case
-dotnet_naming_style.i_upper_camel_case_style.required_prefix=I
-dotnet_naming_style.lower_camel_case_style.capitalization=camel_case
-dotnet_naming_style.lower_camel_case_style.required_prefix=_
-dotnet_naming_style.lower_camel_case_style_1.capitalization=camel_case
-dotnet_naming_style.t_upper_camel_case_style.capitalization=pascal_case
-dotnet_naming_style.t_upper_camel_case_style.required_prefix=T
-dotnet_naming_style.upper_camel_case_style.capitalization=pascal_case
-dotnet_naming_symbols.constants_symbols.applicable_accessibilities=public,internal,protected,protected_internal,private_protected
-dotnet_naming_symbols.constants_symbols.applicable_kinds=field
-dotnet_naming_symbols.constants_symbols.required_modifiers=const
-dotnet_naming_symbols.event_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.event_symbols.applicable_kinds=event
-dotnet_naming_symbols.interfaces_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.interfaces_symbols.applicable_kinds=interface
-dotnet_naming_symbols.locals_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.locals_symbols.applicable_kinds=local
-dotnet_naming_symbols.local_constants_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.local_constants_symbols.applicable_kinds=local
-dotnet_naming_symbols.local_constants_symbols.required_modifiers=const
-dotnet_naming_symbols.local_functions_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.local_functions_symbols.applicable_kinds=local_function
-dotnet_naming_symbols.method_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.method_symbols.applicable_kinds=method
-dotnet_naming_symbols.parameters_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.parameters_symbols.applicable_kinds=parameter
-dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities=private
-dotnet_naming_symbols.private_constants_symbols.applicable_kinds=field
-dotnet_naming_symbols.private_constants_symbols.required_modifiers=const
-dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities=private
-dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds=field
-dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities=private
-dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds=field
-dotnet_naming_symbols.private_static_fields_symbols.required_modifiers=static
-dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities=private
-dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds=field
-dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers=static,readonly
-dotnet_naming_symbols.property_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.property_symbols.applicable_kinds=property
-dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities=public,internal,protected,protected_internal,private_protected
-dotnet_naming_symbols.public_fields_symbols.applicable_kinds=field
-dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities=public,internal,protected,protected_internal,private_protected
-dotnet_naming_symbols.static_readonly_symbols.applicable_kinds=field
-dotnet_naming_symbols.static_readonly_symbols.required_modifiers=static,readonly
-dotnet_naming_symbols.types_and_namespaces_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.types_and_namespaces_symbols.applicable_kinds=namespace,class,struct,enum,delegate
-dotnet_naming_symbols.type_parameters_symbols.applicable_accessibilities=*
-dotnet_naming_symbols.type_parameters_symbols.applicable_kinds=type_parameter
-dotnet_separate_import_directive_groups=false
-dotnet_sort_system_directives_first=true
-dotnet_style_parentheses_in_arithmetic_binary_operators=never_if_unnecessary:suggestion
-dotnet_style_parentheses_in_other_binary_operators=never_if_unnecessary:suggestion
-dotnet_style_parentheses_in_relational_binary_operators=never_if_unnecessary:suggestion
+dotnet_style_parentheses_in_arithmetic_binary_operators=never_if_unnecessary:none
+dotnet_style_parentheses_in_other_binary_operators=never_if_unnecessary:none
+dotnet_style_parentheses_in_relational_binary_operators=never_if_unnecessary:none
dotnet_style_predefined_type_for_locals_parameters_members=true:suggestion
dotnet_style_predefined_type_for_member_access=true:suggestion
dotnet_style_qualification_for_event=false:suggestion
@@ -358,3280 +29,57 @@ dotnet_style_qualification_for_field=false:suggestion
dotnet_style_qualification_for_method=false:suggestion
dotnet_style_qualification_for_property=false:suggestion
dotnet_style_require_accessibility_modifiers=for_non_interface_members:suggestion
-file_header_template=
# ReSharper properties
-resharper_accessor_owner_body=expression_body
-resharper_alignment_tab_fill_style=use_spaces
-resharper_align_first_arg_by_paren=false
-resharper_align_linq_query=false
-resharper_align_multiline_argument=true
-resharper_align_multiline_array_and_object_initializer=false
-resharper_align_multiline_array_initializer=true
resharper_align_multiline_binary_expressions_chain=false
-resharper_align_multiline_binary_patterns=false
-resharper_align_multiline_ctor_init=true
-resharper_align_multiline_expression_braces=false
-resharper_align_multiline_implements_list=true
-resharper_align_multiline_property_pattern=false
-resharper_align_multiline_statement_conditions=true
-resharper_align_multiline_switch_expression=false
-resharper_align_multiline_type_argument=true
-resharper_align_multiline_type_parameter=true
-resharper_align_multline_type_parameter_constrains=true
-resharper_align_multline_type_parameter_list=false
-resharper_align_tuple_components=false
-resharper_align_union_type_usage=true
-resharper_allow_alias=true
-resharper_allow_comment_after_lbrace=false
-resharper_allow_far_alignment=false
-resharper_always_use_end_of_line_brace_style=false
-resharper_apply_auto_detected_rules=false
-resharper_apply_on_completion=false
-resharper_arguments_anonymous_function=positional
-resharper_arguments_literal=positional
-resharper_arguments_named=positional
-resharper_arguments_other=positional
-resharper_arguments_skip_single=false
-resharper_arguments_string_literal=positional
-resharper_attribute_style=do_not_touch
-resharper_autodetect_indent_settings=false
-resharper_blank_lines_after_block_statements=1
-resharper_blank_lines_after_case=0
-resharper_blank_lines_after_control_transfer_statements=1
-resharper_blank_lines_after_file_scoped_namespace_directive=1
-resharper_blank_lines_after_imports=1
-resharper_blank_lines_after_multiline_statements=0
-resharper_blank_lines_after_options=1
-resharper_blank_lines_after_start_comment=1
-resharper_blank_lines_after_using_list=1
-resharper_blank_lines_around_accessor=0
-resharper_blank_lines_around_auto_property=1
-resharper_blank_lines_around_block_case_section=0
-resharper_blank_lines_around_class_definition=1
-resharper_blank_lines_around_field=1
-resharper_blank_lines_around_function_declaration=0
-resharper_blank_lines_around_function_definition=1
-resharper_blank_lines_around_global_attribute=0
-resharper_blank_lines_around_invocable=1
-resharper_blank_lines_around_local_method=1
-resharper_blank_lines_around_multiline_case_section=0
-resharper_blank_lines_around_namespace=1
-resharper_blank_lines_around_other_declaration=0
-resharper_blank_lines_around_property=1
-resharper_blank_lines_around_razor_functions=1
-resharper_blank_lines_around_razor_helpers=1
-resharper_blank_lines_around_razor_sections=1
-resharper_blank_lines_around_region=1
-resharper_blank_lines_around_single_line_accessor=0
-resharper_blank_lines_around_single_line_auto_property=0
-resharper_blank_lines_around_single_line_field=0
-resharper_blank_lines_around_single_line_function_definition=0
-resharper_blank_lines_around_single_line_invocable=0
-resharper_blank_lines_around_single_line_local_method=0
-resharper_blank_lines_around_single_line_property=0
-resharper_blank_lines_around_single_line_type=0
-resharper_blank_lines_around_type=1
-resharper_blank_lines_before_block_statements=0
-resharper_blank_lines_before_case=0
-resharper_blank_lines_before_control_transfer_statements=0
-resharper_blank_lines_before_multiline_statements=0
-resharper_blank_lines_before_single_line_comment=0
-resharper_blank_lines_inside_namespace=0
-resharper_blank_lines_inside_region=1
-resharper_blank_lines_inside_type=0
-resharper_blank_line_after_pi=true
-resharper_braces_for_dowhile=required
-resharper_braces_for_fixed=required
-resharper_braces_for_for=required_for_multiline
-resharper_braces_for_foreach=required_for_multiline
-resharper_braces_for_ifelse=not_required_for_both
-resharper_braces_for_lock=required
-resharper_braces_for_using=required
-resharper_braces_for_while=required_for_multiline
+resharper_align_multiline_calls_chain=false
+resharper_autodetect_indent_settings=true
resharper_braces_redundant=true
-resharper_break_template_declaration=line_break
-resharper_can_use_global_alias=true
-resharper_configure_await_analysis_mode=disabled
resharper_constructor_or_destructor_body=expression_body
-resharper_continuous_indent_multiplier=1
-resharper_continuous_line_indent=single
-resharper_cpp_align_multiline_argument=true
-resharper_cpp_align_multiline_calls_chain=true
-resharper_cpp_align_multiline_extends_list=true
-resharper_cpp_align_multiline_for_stmt=true
-resharper_cpp_align_multiline_parameter=true
-resharper_cpp_align_multiple_declaration=true
-resharper_cpp_align_ternary=align_not_nested
-resharper_cpp_anonymous_method_declaration_braces=next_line
-resharper_cpp_case_block_braces=next_line_shifted_2
-resharper_cpp_empty_block_style=multiline
-resharper_cpp_indent_switch_labels=false
-resharper_cpp_insert_final_newline=false
-resharper_cpp_int_align_comments=false
-resharper_cpp_invocable_declaration_braces=next_line
-resharper_cpp_max_line_length=120
-resharper_cpp_new_line_before_catch=true
-resharper_cpp_new_line_before_else=true
-resharper_cpp_new_line_before_while=true
-resharper_cpp_other_braces=next_line
-resharper_cpp_space_around_binary_operator=true
-resharper_cpp_type_declaration_braces=next_line
-resharper_cpp_wrap_arguments_style=wrap_if_long
-resharper_cpp_wrap_lines=true
-resharper_cpp_wrap_parameters_style=wrap_if_long
-resharper_csharp_align_multiline_argument=false
-resharper_csharp_align_multiline_calls_chain=false
-resharper_csharp_align_multiline_expression=false
-resharper_csharp_align_multiline_extends_list=false
-resharper_csharp_align_multiline_for_stmt=false
-resharper_csharp_align_multiline_parameter=false
-resharper_csharp_align_multiple_declaration=true
resharper_csharp_empty_block_style=together
-resharper_csharp_insert_final_newline=true
-resharper_csharp_int_align_comments=true
resharper_csharp_max_line_length=144
-resharper_csharp_naming_rule.enum_member=AaBb
-resharper_csharp_naming_rule.method_property_event=AaBb
-resharper_csharp_naming_rule.other=AaBb
-resharper_csharp_new_line_before_while=false
-resharper_csharp_prefer_qualified_reference=false
-resharper_csharp_space_after_unary_operator=false
-resharper_csharp_wrap_arguments_style=wrap_if_long
-resharper_csharp_wrap_before_binary_opsign=true
-resharper_csharp_wrap_for_stmt_header_style=wrap_if_long
-resharper_csharp_wrap_lines=true
-resharper_csharp_wrap_parameters_style=wrap_if_long
-resharper_css_brace_style=end_of_line
-resharper_css_insert_final_newline=false
-resharper_css_keep_blank_lines_between_declarations=1
-resharper_css_max_line_length=120
-resharper_css_wrap_lines=true
-resharper_cxxcli_property_declaration_braces=next_line
-resharper_declarations_style=separate_lines
-resharper_default_exception_variable_name=e
-resharper_default_value_when_type_evident=default_literal
-resharper_default_value_when_type_not_evident=default_literal
-resharper_delete_quotes_from_solid_values=false
-resharper_disable_blank_line_changes=false
-resharper_disable_formatter=false
-resharper_disable_indenter=false
-resharper_disable_int_align=false
-resharper_disable_line_break_changes=false
-resharper_disable_line_break_removal=false
-resharper_disable_space_changes=false
-resharper_disable_space_changes_before_trailing_comment=false
-resharper_dont_remove_extra_blank_lines=false
-resharper_enable_wrapping=false
-resharper_enforce_line_ending_style=false
-resharper_event_handler_pattern_long=$object$On$event$
-resharper_event_handler_pattern_short=On$event$
-resharper_expression_braces=inside
-resharper_expression_pars=inside
-resharper_extra_spaces=remove_all
-resharper_force_attribute_style=separate
-resharper_force_chop_compound_do_expression=false
-resharper_force_chop_compound_if_expression=false
-resharper_force_chop_compound_while_expression=false
-resharper_force_control_statements_braces=do_not_change
-resharper_force_linebreaks_inside_complex_literals=true
-resharper_force_variable_declarations_on_new_line=false
-resharper_format_leading_spaces_decl=false
-resharper_free_block_braces=next_line
-resharper_function_declaration_return_type_style=do_not_change
-resharper_function_definition_return_type_style=do_not_change
-resharper_generator_mode=false
-resharper_html_attribute_indent=align_by_first_attribute
-resharper_html_insert_final_newline=false
-resharper_html_linebreak_before_elements=body,div,p,form,h1,h2,h3
-resharper_html_max_blank_lines_between_tags=2
-resharper_html_max_line_length=120
-resharper_html_pi_attribute_style=on_single_line
-resharper_html_space_before_self_closing=false
-resharper_html_wrap_lines=true
-resharper_ignore_space_preservation=false
-resharper_include_prefix_comment_in_indent=false
-resharper_indent_access_specifiers_from_class=false
-resharper_indent_aligned_ternary=true
-resharper_indent_anonymous_method_block=false
-resharper_indent_braces_inside_statement_conditions=true
-resharper_indent_case_from_select=true
-resharper_indent_child_elements=OneIndent
-resharper_indent_class_members_from_access_specifiers=false
-resharper_indent_comment=true
-resharper_indent_inside_namespace=true
-resharper_indent_invocation_pars=inside
-resharper_indent_left_par_inside_expression=false
-resharper_indent_method_decl_pars=inside
-resharper_indent_nested_fixed_stmt=false
-resharper_indent_nested_foreach_stmt=true
-resharper_indent_nested_for_stmt=true
-resharper_indent_nested_lock_stmt=false
-resharper_indent_nested_usings_stmt=false
-resharper_indent_nested_while_stmt=true
-resharper_indent_pars=inside
-resharper_indent_preprocessor_directives=none
-resharper_indent_preprocessor_if=no_indent
-resharper_indent_preprocessor_other=no_indent
-resharper_indent_preprocessor_region=usual_indent
-resharper_indent_statement_pars=inside
-resharper_indent_text=OneIndent
-resharper_indent_typearg_angles=inside
-resharper_indent_typeparam_angles=inside
-resharper_indent_type_constraints=true
-resharper_indent_wrapped_function_names=false
-resharper_instance_members_qualify_declared_in=this_class, base_class
-resharper_int_align=true
+resharper_csharp_space_within_array_access_brackets=true
+resharper_enforce_line_ending_style=true
resharper_int_align_assignments=true
-resharper_int_align_binary_expressions=false
-resharper_int_align_declaration_names=false
-resharper_int_align_eq=false
+resharper_int_align_comments=true
resharper_int_align_fields=true
-resharper_int_align_fix_in_adjacent=true
-resharper_int_align_invocations=true
-resharper_int_align_methods=true
+resharper_int_align_invocations=false
resharper_int_align_nested_ternary=true
-resharper_int_align_parameters=false
-resharper_int_align_properties=true
-resharper_int_align_property_patterns=true
+resharper_int_align_properties=false
resharper_int_align_switch_expressions=true
resharper_int_align_switch_sections=true
resharper_int_align_variables=true
-resharper_js_align_multiline_parameter=false
-resharper_js_align_multiple_declaration=false
-resharper_js_align_ternary=none
-resharper_js_brace_style=end_of_line
-resharper_js_empty_block_style=multiline
-resharper_js_indent_switch_labels=false
-resharper_js_insert_final_newline=false
-resharper_js_keep_blank_lines_between_declarations=2
-resharper_js_max_line_length=120
-resharper_js_new_line_before_catch=false
-resharper_js_new_line_before_else=false
-resharper_js_new_line_before_finally=false
-resharper_js_new_line_before_while=false
-resharper_js_space_around_binary_operator=true
-resharper_js_wrap_arguments_style=chop_if_long
-resharper_js_wrap_before_binary_opsign=false
-resharper_js_wrap_for_stmt_header_style=chop_if_long
-resharper_js_wrap_lines=true
-resharper_js_wrap_parameters_style=chop_if_long
-resharper_keep_blank_lines_in_code=2
-resharper_keep_blank_lines_in_declarations=2
-resharper_keep_existing_attribute_arrangement=false
-resharper_keep_existing_declaration_block_arrangement=false
-resharper_keep_existing_declaration_parens_arrangement=true
-resharper_keep_existing_embedded_arrangement=false
-resharper_keep_existing_embedded_block_arrangement=false
-resharper_keep_existing_enum_arrangement=false
-resharper_keep_existing_expr_member_arrangement=false
-resharper_keep_existing_initializer_arrangement=false
-resharper_keep_existing_invocation_parens_arrangement=true
-resharper_keep_existing_property_patterns_arrangement=true
-resharper_keep_existing_switch_expression_arrangement=false
-resharper_keep_nontrivial_alias=true
-resharper_keep_user_linebreaks=true
-resharper_keep_user_wrapping=true
-resharper_linebreaks_around_razor_statements=true
-resharper_linebreaks_inside_tags_for_elements_longer_than=2147483647
-resharper_linebreaks_inside_tags_for_elements_with_child_elements=true
-resharper_linebreaks_inside_tags_for_multiline_elements=true
-resharper_linebreak_before_all_elements=false
-resharper_linebreak_before_multiline_elements=true
-resharper_linebreak_before_singleline_elements=false
-resharper_line_break_after_colon_in_member_initializer_lists=do_not_change
-resharper_line_break_after_comma_in_member_initializer_lists=false
-resharper_line_break_before_comma_in_member_initializer_lists=false
-resharper_line_break_before_requires_clause=do_not_change
-resharper_linkage_specification_braces=end_of_line
-resharper_linkage_specification_indentation=none
resharper_local_function_body=expression_body
-resharper_macro_block_begin=
-resharper_macro_block_end=
-resharper_max_array_initializer_elements_on_line=10000
-resharper_max_attribute_length_for_same_line=38
-resharper_max_enum_members_on_line=1
-resharper_max_formal_parameters_on_line=10000
-resharper_max_initializer_elements_on_line=1
-resharper_max_invocation_arguments_on_line=10000
-resharper_media_query_style=same_line
-resharper_member_initializer_list_style=do_not_change
resharper_method_or_operator_body=expression_body
-resharper_min_blank_lines_after_imports=0
-resharper_min_blank_lines_around_fields=0
-resharper_min_blank_lines_around_functions=1
-resharper_min_blank_lines_around_types=1
-resharper_min_blank_lines_between_declarations=1
-resharper_namespace_declaration_braces=next_line
-resharper_namespace_indentation=all
-resharper_nested_ternary_style=autodetect
-resharper_new_line_before_enumerators=true
-resharper_normalize_tag_names=false
-resharper_no_indent_inside_elements=html,body,thead,tbody,tfoot
-resharper_no_indent_inside_if_element_longer_than=200
-resharper_object_creation_when_type_evident=target_typed
-resharper_object_creation_when_type_not_evident=explicitly_typed
-resharper_old_engine=false
-resharper_options_braces_pointy=false
-resharper_outdent_binary_ops=true
-resharper_outdent_binary_pattern_ops=false
-resharper_outdent_commas=false
-resharper_outdent_dots=false
-resharper_outdent_namespace_member=false
-resharper_outdent_statement_labels=false
-resharper_outdent_ternary_ops=false
-resharper_parentheses_non_obvious_operations=none, bitwise, bitwise_inclusive_or, bitwise_exclusive_or, shift, bitwise_and
-resharper_parentheses_redundancy_style=remove_if_not_clarifies_precedence
-resharper_parentheses_same_type_operations=false
-resharper_pi_attributes_indent=align_by_first_attribute
resharper_place_attribute_on_same_line=false
-resharper_place_class_decorator_on_the_same_line=false
-resharper_place_comments_at_first_column=false
-resharper_place_constructor_initializer_on_same_line=false
-resharper_place_each_decorator_on_new_line=false
-resharper_place_event_attribute_on_same_line=false
-resharper_place_expr_accessor_on_single_line=true
-resharper_place_expr_method_on_single_line=false
-resharper_place_expr_property_on_single_line=false
-resharper_place_field_decorator_on_the_same_line=false
-resharper_place_linq_into_on_new_line=true
-resharper_place_method_decorator_on_the_same_line=false
-resharper_place_namespace_definitions_on_same_line=false
-resharper_place_property_attribute_on_same_line=false
-resharper_place_property_decorator_on_the_same_line=false
-resharper_place_simple_case_statement_on_same_line=if_owner_is_single_line
-resharper_place_simple_embedded_statement_on_same_line=false
-resharper_place_simple_enum_on_single_line=true
-resharper_place_simple_initializer_on_single_line=true
-resharper_place_simple_property_pattern_on_single_line=true
-resharper_place_simple_switch_expression_on_single_line=true
-resharper_place_template_args_on_new_line=false
-resharper_place_type_constraints_on_same_line=true
-resharper_prefer_explicit_discard_declaration=false
-resharper_prefer_separate_deconstructed_variables_declaration=false
-resharper_preserve_spaces_inside_tags=pre,textarea
-resharper_properties_style=separate_lines_for_nonsingle
-resharper_protobuf_brace_style=end_of_line
-resharper_protobuf_empty_block_style=together_same_line
-resharper_protobuf_insert_final_newline=false
-resharper_protobuf_max_line_length=120
-resharper_protobuf_wrap_lines=true
-resharper_qualified_using_at_nested_scope=false
-resharper_quote_style=doublequoted
-resharper_razor_prefer_qualified_reference=true
-resharper_remove_blank_lines_near_braces=false
-resharper_remove_blank_lines_near_braces_in_code=true
-resharper_remove_blank_lines_near_braces_in_declarations=true
-resharper_remove_this_qualifier=true
-resharper_requires_expression_braces=next_line
-resharper_resx_attribute_indent=single_indent
-resharper_resx_insert_final_newline=false
-resharper_resx_linebreak_before_elements=
-resharper_resx_max_blank_lines_between_tags=0
-resharper_resx_max_line_length=2147483647
-resharper_resx_pi_attribute_style=do_not_touch
-resharper_resx_space_before_self_closing=false
-resharper_resx_wrap_lines=false
-resharper_resx_wrap_tags_and_pi=false
-resharper_resx_wrap_text=false
-resharper_selector_style=same_line
-resharper_show_autodetect_configure_formatting_tip=true
-resharper_simple_blocks=do_not_change
-resharper_simple_block_style=do_not_change
-resharper_simple_case_statement_style=do_not_change
-resharper_simple_embedded_statement_style=do_not_change
-resharper_single_statement_function_style=do_not_change
-resharper_sort_attributes=false
-resharper_sort_class_selectors=false
-resharper_sort_usings=true
-resharper_sort_usings_lowercase_first=false
-resharper_spaces_around_eq_in_attribute=false
-resharper_spaces_around_eq_in_pi_attribute=false
-resharper_spaces_inside_tags=false
-resharper_space_after_arrow=true
-resharper_space_after_attributes=true
-resharper_space_after_attribute_target_colon=true
resharper_space_after_cast=false
-resharper_space_after_colon=true
-resharper_space_after_colon_in_case=true
-resharper_space_after_colon_in_inheritance_clause=true
-resharper_space_after_colon_in_type_annotation=true
-resharper_space_after_comma=true
-resharper_space_after_for_colon=true
-resharper_space_after_function_comma=true
-resharper_space_after_keywords_in_control_flow_statements=true
-resharper_space_after_last_attribute=false
-resharper_space_after_last_pi_attribute=false
-resharper_space_after_media_colon=true
-resharper_space_after_media_comma=true
-resharper_space_after_operator_keyword=true
-resharper_space_after_property_colon=true
-resharper_space_after_property_semicolon=true
-resharper_space_after_ptr_in_data_member=true
-resharper_space_after_ptr_in_data_members=false
-resharper_space_after_ptr_in_method=true
-resharper_space_after_ref_in_data_member=true
-resharper_space_after_ref_in_data_members=false
-resharper_space_after_ref_in_method=true
-resharper_space_after_selector_comma=true
-resharper_space_after_semicolon_in_for_statement=true
-resharper_space_after_separator=false
-resharper_space_after_ternary_colon=true
-resharper_space_after_ternary_quest=true
-resharper_space_after_triple_slash=true
-resharper_space_after_type_parameter_constraint_colon=true
-resharper_space_around_additive_op=true
-resharper_space_around_alias_eq=true
-resharper_space_around_assignment_op=true
-resharper_space_around_assignment_operator=true
-resharper_space_around_attribute_match_operator=false
-resharper_space_around_deref_in_trailing_return_type=true
-resharper_space_around_lambda_arrow=true
-resharper_space_around_member_access_operator=false
-resharper_space_around_operator=true
-resharper_space_around_pipe_or_amper_in_type_usage=true
-resharper_space_around_relational_op=true
-resharper_space_around_selector_operator=true
-resharper_space_around_shift_op=true
-resharper_space_around_stmt_colon=true
-resharper_space_around_ternary_operator=true
-resharper_space_before_array_rank_parentheses=false
-resharper_space_before_arrow=true
-resharper_space_before_attribute_target_colon=false
-resharper_space_before_checked_parentheses=false
-resharper_space_before_colon=false
-resharper_space_before_colon_in_case=false
-resharper_space_before_colon_in_inheritance_clause=true
-resharper_space_before_colon_in_type_annotation=false
-resharper_space_before_comma=false
-resharper_space_before_default_parentheses=false
-resharper_space_before_empty_invocation_parentheses=false
-resharper_space_before_empty_method_parentheses=false
-resharper_space_before_for_colon=true
-resharper_space_before_function_comma=false
-resharper_space_before_initializer_braces=false
-resharper_space_before_invocation_parentheses=false
-resharper_space_before_label_colon=false
-resharper_space_before_lambda_parentheses=false
-resharper_space_before_media_colon=false
-resharper_space_before_media_comma=false
-resharper_space_before_method_parentheses=false
-resharper_space_before_nameof_parentheses=false
-resharper_space_before_new_parentheses=false
-resharper_space_before_nullable_mark=false
-resharper_space_before_open_square_brackets=false
-resharper_space_before_pointer_asterik_declaration=false
-resharper_space_before_property_colon=false
-resharper_space_before_property_semicolon=false
-resharper_space_before_ptr_in_abstract_decl=false
-resharper_space_before_ptr_in_data_member=false
-resharper_space_before_ptr_in_data_members=true
-resharper_space_before_ptr_in_method=false
-resharper_space_before_ref_in_abstract_decl=false
-resharper_space_before_ref_in_data_member=false
-resharper_space_before_ref_in_data_members=true
-resharper_space_before_ref_in_method=false
-resharper_space_before_selector_comma=false
-resharper_space_before_semicolon=false
-resharper_space_before_semicolon_in_for_statement=false
-resharper_space_before_separator=false
-resharper_space_before_singleline_accessorholder=true
-resharper_space_before_sizeof_parentheses=false
-resharper_space_before_template_args=false
-resharper_space_before_template_params=true
-resharper_space_before_ternary_colon=true
-resharper_space_before_ternary_quest=true
-resharper_space_before_trailing_comment=true
-resharper_space_before_typeof_parentheses=false
-resharper_space_before_type_argument_angle=false
-resharper_space_before_type_parameters_brackets=false
-resharper_space_before_type_parameter_angle=false
-resharper_space_before_type_parameter_constraint_colon=true
-resharper_space_before_type_parameter_parentheses=true
-resharper_space_between_accessors_in_singleline_property=true
-resharper_space_between_attribute_sections=true
-resharper_space_between_closing_angle_brackets_in_template_args=false
-resharper_space_between_empty_square_brackets=false
-resharper_space_between_keyword_and_expression=true
-resharper_space_between_keyword_and_type=true
-resharper_space_between_method_call_empty_parameter_list_parentheses=false
-resharper_space_between_method_call_name_and_opening_parenthesis=false
-resharper_space_between_method_call_parameter_list_parentheses=false
-resharper_space_between_method_declaration_empty_parameter_list_parentheses=false
-resharper_space_between_method_declaration_name_and_open_parenthesis=false
-resharper_space_between_method_declaration_parameter_list_parentheses=false
-resharper_space_between_parentheses_of_control_flow_statements=false
-resharper_space_between_square_brackets=false
-resharper_space_between_typecast_parentheses=false
-resharper_space_colon_after=true
-resharper_space_colon_before=false
-resharper_space_comma=true
-resharper_space_equals=true
-resharper_space_inside_braces=true
-resharper_space_in_singleline_accessorholder=true
-resharper_space_in_singleline_anonymous_method=true
-resharper_space_in_singleline_method=true
-resharper_space_near_postfix_and_prefix_op=false
-resharper_space_within_array_initialization_braces=false
-resharper_space_within_array_rank_empty_parentheses=false
-resharper_space_within_array_rank_parentheses=false
-resharper_space_within_attribute_angles=false
-resharper_space_within_attribute_match_brackets=false
-resharper_space_within_checked_parentheses=false
-resharper_space_within_default_parentheses=false
-resharper_space_within_empty_braces=true
-resharper_space_within_empty_initializer_braces=false
-resharper_space_within_empty_invocation_parentheses=false
-resharper_space_within_empty_method_parentheses=false
-resharper_space_within_empty_object_literal_braces=false
-resharper_space_within_empty_template_params=false
-resharper_space_within_expression_parentheses=false
-resharper_space_within_function_parentheses=false
-resharper_space_within_import_braces=true
-resharper_space_within_initializer_braces=false
-resharper_space_within_invocation_parentheses=false
-resharper_space_within_media_block=true
-resharper_space_within_media_parentheses=false
-resharper_space_within_method_parentheses=false
-resharper_space_within_nameof_parentheses=false
-resharper_space_within_new_parentheses=false
-resharper_space_within_object_literal_braces=true
-resharper_space_within_parentheses=false
-resharper_space_within_property_block=true
+resharper_space_within_checked_parentheses=true
+resharper_space_within_default_parentheses=true
+resharper_space_within_nameof_parentheses=true
resharper_space_within_single_line_array_initializer_braces=true
-resharper_space_within_sizeof_parentheses=false
-resharper_space_within_template_args=false
-resharper_space_within_template_argument=false
-resharper_space_within_template_params=false
-resharper_space_within_tuple_parentheses=false
-resharper_space_within_typeof_parentheses=false
-resharper_space_within_type_argument_angles=false
-resharper_space_within_type_parameters_brackets=false
-resharper_space_within_type_parameter_angles=false
-resharper_space_within_type_parameter_parentheses=false
-resharper_special_else_if_treatment=true
-resharper_static_members_qualify_members=none
-resharper_static_members_qualify_with=declared_type
-resharper_stick_comment=true
-resharper_support_vs_event_naming_pattern=true
-resharper_termination_style=ensure_semicolon
-resharper_toplevel_function_declaration_return_type_style=do_not_change
-resharper_toplevel_function_definition_return_type_style=do_not_change
-resharper_trailing_comma_in_multiline_lists=true
-resharper_trailing_comma_in_singleline_lists=false
-resharper_types_braces=end_of_line
-resharper_use_continuous_indent_inside_initializer_braces=true
-resharper_use_continuous_indent_inside_parens=true
-resharper_use_continuous_line_indent_in_expression_braces=false
-resharper_use_continuous_line_indent_in_method_pars=false
-resharper_use_heuristics_for_body_style=true
-resharper_use_indents_from_main_language_in_file=true
-resharper_use_indent_from_previous_element=true
+resharper_space_within_sizeof_parentheses=true
+resharper_space_within_typeof_parentheses=true
+resharper_space_within_type_argument_angles=true
+resharper_space_within_type_parameter_angles=true
resharper_use_indent_from_vs=false
-resharper_use_roslyn_logic_for_evident_types=false
-resharper_vb_align_multiline_argument=true
-resharper_vb_align_multiline_expression=true
-resharper_vb_align_multiline_parameter=true
-resharper_vb_align_multiple_declaration=true
-resharper_vb_insert_final_newline=false
-resharper_vb_max_line_length=120
-resharper_vb_place_field_attribute_on_same_line=true
-resharper_vb_place_method_attribute_on_same_line=false
-resharper_vb_place_type_attribute_on_same_line=false
-resharper_vb_prefer_qualified_reference=false
-resharper_vb_space_after_unary_operator=true
-resharper_vb_space_around_multiplicative_op=false
-resharper_vb_wrap_arguments_style=wrap_if_long
-resharper_vb_wrap_before_binary_opsign=false
-resharper_vb_wrap_lines=true
-resharper_vb_wrap_parameters_style=wrap_if_long
-resharper_wrap_after_binary_opsign=true
-resharper_wrap_after_declaration_lpar=false
-resharper_wrap_after_dot=false
-resharper_wrap_after_dot_in_method_calls=false
-resharper_wrap_after_expression_lbrace=true
-resharper_wrap_after_invocation_lpar=false
-resharper_wrap_around_elements=true
-resharper_wrap_array_initializer_style=chop_always
-resharper_wrap_array_literals=chop_if_long
-resharper_wrap_base_clause_style=wrap_if_long
-resharper_wrap_before_arrow_with_expressions=true
-resharper_wrap_before_binary_pattern_op=true
-resharper_wrap_before_colon=false
-resharper_wrap_before_comma=false
-resharper_wrap_before_comma_in_base_clause=false
-resharper_wrap_before_declaration_lpar=false
-resharper_wrap_before_declaration_rpar=false
-resharper_wrap_before_dot=true
-resharper_wrap_before_eq=false
-resharper_wrap_before_expression_rbrace=true
-resharper_wrap_before_extends_colon=false
-resharper_wrap_before_first_type_parameter_constraint=false
-resharper_wrap_before_invocation_lpar=false
-resharper_wrap_before_invocation_rpar=false
-resharper_wrap_before_linq_expression=false
-resharper_wrap_before_ternary_opsigns=true
-resharper_wrap_before_type_parameter_langle=false
-resharper_wrap_braced_init_list_style=wrap_if_long
-resharper_wrap_chained_binary_expressions=chop_if_long
-resharper_wrap_chained_binary_patterns=wrap_if_long
-resharper_wrap_chained_method_calls=wrap_if_long
-resharper_wrap_ctor_initializer_style=wrap_if_long
-resharper_wrap_enumeration_style=chop_if_long
-resharper_wrap_enum_declaration=chop_always
-resharper_wrap_enum_style=do_not_change
-resharper_wrap_extends_list_style=wrap_if_long
-resharper_wrap_imports=chop_if_long
-resharper_wrap_multiple_declaration_style=chop_if_long
-resharper_wrap_multiple_type_parameter_constraints_style=chop_if_long
-resharper_wrap_object_literals=chop_if_long
-resharper_wrap_property_pattern=chop_if_long
-resharper_wrap_switch_expression=chop_always
-resharper_wrap_ternary_expr_style=chop_if_long
-resharper_wrap_union_type_usage=chop_if_long
-resharper_wrap_verbatim_interpolated_strings=no_wrap
-resharper_xmldoc_attribute_indent=single_indent
-resharper_xmldoc_insert_final_newline=false
-resharper_xmldoc_linebreak_before_elements=summary,remarks,example,returns,param,typeparam,value,para
-resharper_xmldoc_max_blank_lines_between_tags=0
-resharper_xmldoc_max_line_length=120
-resharper_xmldoc_pi_attribute_style=do_not_touch
-resharper_xmldoc_space_before_self_closing=true
-resharper_xmldoc_wrap_lines=true
-resharper_xmldoc_wrap_tags_and_pi=true
-resharper_xmldoc_wrap_text=true
-resharper_xml_attribute_indent=align_by_first_attribute
-resharper_xml_insert_final_newline=false
-resharper_xml_linebreak_before_elements=
-resharper_xml_max_blank_lines_between_tags=2
-resharper_xml_max_line_length=120
-resharper_xml_pi_attribute_style=do_not_touch
-resharper_xml_space_before_self_closing=true
-resharper_xml_wrap_lines=true
-resharper_xml_wrap_tags_and_pi=true
-resharper_xml_wrap_text=false
+resharper_wrap_lines=true
# ReSharper inspection severities
-resharper_abstract_class_constructor_can_be_made_protected_highlighting=hint
-resharper_access_rights_in_text_highlighting=warning
-resharper_access_to_disposed_closure_highlighting=warning
-resharper_access_to_for_each_variable_in_closure_highlighting=warning
-resharper_access_to_modified_closure_highlighting=warning
-resharper_access_to_static_member_via_derived_type_highlighting=warning
-resharper_address_of_marshal_by_ref_object_highlighting=warning
-resharper_amd_dependency_path_problem_highlighting=none
-resharper_amd_external_module_highlighting=suggestion
-resharper_angular_html_banana_highlighting=warning
-resharper_annotate_can_be_null_parameter_highlighting=none
-resharper_annotate_can_be_null_type_member_highlighting=none
-resharper_annotate_not_null_parameter_highlighting=none
-resharper_annotate_not_null_type_member_highlighting=none
-resharper_annotation_conflict_in_hierarchy_highlighting=warning
-resharper_annotation_redundancy_at_value_type_highlighting=warning
-resharper_annotation_redundancy_in_hierarchy_highlighting=warning
-resharper_arguments_style_anonymous_function_highlighting=hint
-resharper_arguments_style_literal_highlighting=hint
-resharper_arguments_style_named_expression_highlighting=hint
-resharper_arguments_style_other_highlighting=hint
-resharper_arguments_style_string_literal_highlighting=hint
-resharper_arrange_accessor_owner_body_highlighting=suggestion
-resharper_arrange_attributes_highlighting=none
-resharper_arrange_constructor_or_destructor_body_highlighting=hint
-resharper_arrange_default_value_when_type_evident_highlighting=suggestion
-resharper_arrange_default_value_when_type_not_evident_highlighting=hint
-resharper_arrange_local_function_body_highlighting=hint
-resharper_arrange_method_or_operator_body_highlighting=hint
-resharper_arrange_missing_parentheses_highlighting=hint
-resharper_arrange_namespace_body_highlighting=hint
-resharper_arrange_object_creation_when_type_evident_highlighting=suggestion
-resharper_arrange_object_creation_when_type_not_evident_highlighting=hint
resharper_arrange_redundant_parentheses_highlighting=hint
-resharper_arrange_static_member_qualifier_highlighting=hint
resharper_arrange_this_qualifier_highlighting=hint
-resharper_arrange_trailing_comma_in_multiline_lists_highlighting=hint
-resharper_arrange_trailing_comma_in_singleline_lists_highlighting=hint
resharper_arrange_type_member_modifiers_highlighting=hint
resharper_arrange_type_modifiers_highlighting=hint
-resharper_arrange_var_keywords_in_deconstructing_declaration_highlighting=suggestion
-resharper_asp_content_placeholder_not_resolved_highlighting=error
-resharper_asp_custom_page_parser_filter_type_highlighting=warning
-resharper_asp_dead_code_highlighting=warning
-resharper_asp_entity_highlighting=warning
-resharper_asp_image_highlighting=warning
-resharper_asp_invalid_control_type_highlighting=error
-resharper_asp_not_resolved_highlighting=error
-resharper_asp_ods_method_reference_resolve_error_highlighting=error
-resharper_asp_resolve_warning_highlighting=warning
-resharper_asp_skin_not_resolved_highlighting=error
-resharper_asp_tag_attribute_with_optional_value_highlighting=warning
-resharper_asp_theme_not_resolved_highlighting=error
-resharper_asp_unused_register_directive_highlighting_highlighting=warning
-resharper_asp_warning_highlighting=warning
-resharper_assigned_value_is_never_used_highlighting=warning
-resharper_assigned_value_wont_be_assigned_to_corresponding_field_highlighting=warning
-resharper_assignment_in_conditional_expression_highlighting=warning
-resharper_assignment_in_condition_expression_highlighting=warning
-resharper_assignment_is_fully_discarded_highlighting=warning
-resharper_assign_null_to_not_null_attribute_highlighting=warning
-resharper_assign_to_constant_highlighting=error
-resharper_assign_to_implicit_global_in_function_scope_highlighting=warning
-resharper_asxx_path_error_highlighting=warning
-resharper_async_iterator_invocation_without_await_foreach_highlighting=warning
-resharper_async_void_lambda_highlighting=warning
-resharper_async_void_method_highlighting=none
-resharper_auto_property_can_be_made_get_only_global_highlighting=suggestion
-resharper_auto_property_can_be_made_get_only_local_highlighting=suggestion
-resharper_bad_attribute_brackets_spaces_highlighting=none
-resharper_bad_braces_spaces_highlighting=none
-resharper_bad_child_statement_indent_highlighting=warning
-resharper_bad_colon_spaces_highlighting=none
-resharper_bad_comma_spaces_highlighting=none
-resharper_bad_control_braces_indent_highlighting=suggestion
-resharper_bad_control_braces_line_breaks_highlighting=none
-resharper_bad_declaration_braces_indent_highlighting=none
-resharper_bad_declaration_braces_line_breaks_highlighting=none
-resharper_bad_empty_braces_line_breaks_highlighting=none
-resharper_bad_expression_braces_indent_highlighting=none
-resharper_bad_expression_braces_line_breaks_highlighting=none
-resharper_bad_generic_brackets_spaces_highlighting=none
-resharper_bad_indent_highlighting=none
-resharper_bad_linq_line_breaks_highlighting=none
-resharper_bad_list_line_breaks_highlighting=none
-resharper_bad_member_access_spaces_highlighting=none
-resharper_bad_namespace_braces_indent_highlighting=none
-resharper_bad_parens_line_breaks_highlighting=none
-resharper_bad_parens_spaces_highlighting=none
-resharper_bad_preprocessor_indent_highlighting=none
-resharper_bad_semicolon_spaces_highlighting=none
-resharper_bad_spaces_after_keyword_highlighting=none
-resharper_bad_square_brackets_spaces_highlighting=none
-resharper_bad_switch_braces_indent_highlighting=none
-resharper_bad_symbol_spaces_highlighting=none
-resharper_base_member_has_params_highlighting=warning
-resharper_base_method_call_with_default_parameter_highlighting=warning
-resharper_base_object_equals_is_object_equals_highlighting=warning
-resharper_base_object_get_hash_code_call_in_get_hash_code_highlighting=warning
-resharper_bitwise_operator_on_enum_without_flags_highlighting=warning
-resharper_block_scope_redeclaration_highlighting=error
resharper_built_in_type_reference_style_for_member_access_highlighting=hint
resharper_built_in_type_reference_style_highlighting=hint
-resharper_by_ref_argument_is_volatile_field_highlighting=warning
-resharper_caller_callee_using_error_highlighting=error
-resharper_caller_callee_using_highlighting=warning
-resharper_cannot_apply_equality_operator_to_type_highlighting=warning
-resharper_center_tag_is_obsolete_highlighting=warning
-resharper_check_for_reference_equality_instead_1_highlighting=suggestion
-resharper_check_for_reference_equality_instead_2_highlighting=suggestion
-resharper_check_for_reference_equality_instead_3_highlighting=suggestion
-resharper_check_for_reference_equality_instead_4_highlighting=suggestion
-resharper_check_namespace_highlighting=warning
-resharper_class_cannot_be_instantiated_highlighting=warning
-resharper_class_can_be_sealed_global_highlighting=none
-resharper_class_can_be_sealed_local_highlighting=none
-resharper_class_highlighting=suggestion
-resharper_class_never_instantiated_global_highlighting=suggestion
-resharper_class_never_instantiated_local_highlighting=suggestion
-resharper_class_with_virtual_members_never_inherited_global_highlighting=suggestion
-resharper_class_with_virtual_members_never_inherited_local_highlighting=suggestion
-resharper_clear_attribute_is_obsolete_all_highlighting=warning
-resharper_clear_attribute_is_obsolete_highlighting=warning
-resharper_closure_on_modified_variable_highlighting=warning
-resharper_coerced_equals_using_highlighting=warning
-resharper_coerced_equals_using_with_null_undefined_highlighting=none
-resharper_collection_never_queried_global_highlighting=warning
-resharper_collection_never_queried_local_highlighting=warning
-resharper_collection_never_updated_global_highlighting=warning
-resharper_collection_never_updated_local_highlighting=warning
-resharper_comma_not_valid_here_highlighting=error
-resharper_comment_typo_highlighting=suggestion
-resharper_common_js_external_module_highlighting=suggestion
-resharper_compare_non_constrained_generic_with_null_highlighting=none
-resharper_compare_of_floats_by_equality_operator_highlighting=none
-resharper_conditional_ternary_equal_branch_highlighting=warning
-resharper_condition_is_always_const_highlighting=warning
-resharper_condition_is_always_true_or_false_highlighting=warning
-resharper_confusing_char_as_integer_in_constructor_highlighting=warning
-resharper_constant_conditional_access_qualifier_highlighting=warning
-resharper_constant_null_coalescing_condition_highlighting=warning
-resharper_constructor_call_not_used_highlighting=warning
-resharper_constructor_initializer_loop_highlighting=warning
-resharper_container_annotation_redundancy_highlighting=warning
-resharper_context_value_is_provided_highlighting=none
-resharper_contract_annotation_not_parsed_highlighting=warning
-resharper_convert_closure_to_method_group_highlighting=suggestion
-resharper_convert_conditional_ternary_expression_to_switch_expression_highlighting=hint
-resharper_convert_if_do_to_while_highlighting=suggestion
-resharper_convert_if_statement_to_conditional_ternary_expression_highlighting=suggestion
-resharper_convert_if_statement_to_null_coalescing_assignment_highlighting=suggestion
-resharper_convert_if_statement_to_null_coalescing_expression_highlighting=suggestion
-resharper_convert_if_statement_to_return_statement_highlighting=hint
-resharper_convert_if_statement_to_switch_expression_highlighting=hint
-resharper_convert_if_statement_to_switch_statement_highlighting=hint
-resharper_convert_if_to_or_expression_highlighting=suggestion
-resharper_convert_nullable_to_short_form_highlighting=suggestion
-resharper_convert_switch_statement_to_switch_expression_highlighting=hint
-resharper_convert_to_auto_property_highlighting=suggestion
-resharper_convert_to_auto_property_when_possible_highlighting=hint
-resharper_convert_to_auto_property_with_private_setter_highlighting=hint
-resharper_convert_to_compound_assignment_highlighting=hint
-resharper_convert_to_constant_global_highlighting=hint
-resharper_convert_to_constant_local_highlighting=hint
-resharper_convert_to_lambda_expression_highlighting=suggestion
-resharper_convert_to_lambda_expression_when_possible_highlighting=none
-resharper_convert_to_local_function_highlighting=suggestion
-resharper_convert_to_null_coalescing_compound_assignment_highlighting=suggestion
-resharper_convert_to_primary_constructor_highlighting=suggestion
-resharper_convert_to_static_class_highlighting=suggestion
-resharper_convert_to_using_declaration_highlighting=suggestion
-resharper_convert_to_vb_auto_property_highlighting=suggestion
-resharper_convert_to_vb_auto_property_when_possible_highlighting=hint
-resharper_convert_to_vb_auto_property_with_private_setter_highlighting=hint
-resharper_convert_type_check_pattern_to_null_check_highlighting=warning
-resharper_convert_type_check_to_null_check_highlighting=warning
-resharper_co_variant_array_conversion_highlighting=warning
-resharper_cpp_abstract_class_without_specifier_highlighting=warning
-resharper_cpp_abstract_final_class_highlighting=warning
-resharper_cpp_abstract_virtual_function_call_in_ctor_highlighting=error
-resharper_cpp_access_specifier_with_no_declarations_highlighting=suggestion
-resharper_cpp_assigned_value_is_never_used_highlighting=warning
-resharper_cpp_awaiter_type_is_not_class_highlighting=warning
-resharper_cpp_bad_angle_brackets_spaces_highlighting=none
-resharper_cpp_bad_braces_spaces_highlighting=none
-resharper_cpp_bad_child_statement_indent_highlighting=none
-resharper_cpp_bad_colon_spaces_highlighting=none
-resharper_cpp_bad_comma_spaces_highlighting=none
-resharper_cpp_bad_control_braces_indent_highlighting=none
-resharper_cpp_bad_control_braces_line_breaks_highlighting=none
-resharper_cpp_bad_declaration_braces_indent_highlighting=none
-resharper_cpp_bad_declaration_braces_line_breaks_highlighting=none
-resharper_cpp_bad_empty_braces_line_breaks_highlighting=none
-resharper_cpp_bad_expression_braces_indent_highlighting=none
-resharper_cpp_bad_expression_braces_line_breaks_highlighting=none
-resharper_cpp_bad_indent_highlighting=none
-resharper_cpp_bad_list_line_breaks_highlighting=none
-resharper_cpp_bad_member_access_spaces_highlighting=none
-resharper_cpp_bad_namespace_braces_indent_highlighting=none
-resharper_cpp_bad_parens_line_breaks_highlighting=none
-resharper_cpp_bad_parens_spaces_highlighting=none
-resharper_cpp_bad_semicolon_spaces_highlighting=none
-resharper_cpp_bad_spaces_after_keyword_highlighting=none
-resharper_cpp_bad_square_brackets_spaces_highlighting=none
-resharper_cpp_bad_switch_braces_indent_highlighting=none
-resharper_cpp_bad_symbol_spaces_highlighting=none
-resharper_cpp_boolean_increment_expression_highlighting=warning
-resharper_cpp_boost_format_bad_code_highlighting=warning
-resharper_cpp_boost_format_legacy_code_highlighting=suggestion
-resharper_cpp_boost_format_mixed_args_highlighting=error
-resharper_cpp_boost_format_too_few_args_highlighting=error
-resharper_cpp_boost_format_too_many_args_highlighting=warning
-resharper_cpp_clang_tidy_abseil_duration_addition_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_comparison_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_conversion_cast_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_division_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_factory_float_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_factory_scale_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_subtraction_highlighting=none
-resharper_cpp_clang_tidy_abseil_duration_unnecessary_conversion_highlighting=none
-resharper_cpp_clang_tidy_abseil_faster_strsplit_delimiter_highlighting=none
-resharper_cpp_clang_tidy_abseil_no_internal_dependencies_highlighting=none
-resharper_cpp_clang_tidy_abseil_no_namespace_highlighting=none
-resharper_cpp_clang_tidy_abseil_redundant_strcat_calls_highlighting=none
-resharper_cpp_clang_tidy_abseil_string_find_startswith_highlighting=none
-resharper_cpp_clang_tidy_abseil_string_find_str_contains_highlighting=none
-resharper_cpp_clang_tidy_abseil_str_cat_append_highlighting=none
-resharper_cpp_clang_tidy_abseil_time_comparison_highlighting=none
-resharper_cpp_clang_tidy_abseil_time_subtraction_highlighting=none
-resharper_cpp_clang_tidy_abseil_upgrade_duration_conversions_highlighting=none
-resharper_cpp_clang_tidy_altera_id_dependent_backward_branch_highlighting=none
-resharper_cpp_clang_tidy_altera_kernel_name_restriction_highlighting=none
-resharper_cpp_clang_tidy_altera_single_work_item_barrier_highlighting=none
-resharper_cpp_clang_tidy_altera_struct_pack_align_highlighting=none
-resharper_cpp_clang_tidy_altera_unroll_loops_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_accept4_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_accept_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_creat_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_dup_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_epoll_create1_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_epoll_create_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_fopen_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_inotify_init1_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_inotify_init_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_memfd_create_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_open_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_pipe2_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_pipe_highlighting=none
-resharper_cpp_clang_tidy_android_cloexec_socket_highlighting=none
-resharper_cpp_clang_tidy_android_comparison_in_temp_failure_retry_highlighting=none
-resharper_cpp_clang_tidy_boost_use_to_string_highlighting=suggestion
-resharper_cpp_clang_tidy_bugprone_argument_comment_highlighting=suggestion
-resharper_cpp_clang_tidy_bugprone_assert_side_effect_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_bad_signal_to_kill_thread_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_bool_pointer_implicit_conversion_highlighting=none
-resharper_cpp_clang_tidy_bugprone_branch_clone_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_copy_constructor_init_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_dangling_handle_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_dynamic_static_initializers_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_easily_swappable_parameters_highlighting=none
-resharper_cpp_clang_tidy_bugprone_exception_escape_highlighting=none
-resharper_cpp_clang_tidy_bugprone_fold_init_type_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_forwarding_reference_overload_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_forward_declaration_namespace_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_implicit_widening_of_multiplication_result_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_inaccurate_erase_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_incorrect_roundings_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_infinite_loop_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_integer_division_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_lambda_function_name_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_macro_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_macro_repeated_side_effects_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_misplaced_operator_in_strlen_in_alloc_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_misplaced_pointer_arithmetic_in_alloc_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_misplaced_widening_cast_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_move_forwarding_reference_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_multiple_statement_macro_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_narrowing_conversions_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_not_null_terminated_result_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_no_escape_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_parent_virtual_call_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_posix_return_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_redundant_branch_condition_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_reserved_identifier_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_signal_handler_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_signed_char_misuse_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_sizeof_container_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_sizeof_expression_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_spuriously_wake_up_functions_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_string_constructor_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_string_integer_assignment_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_string_literal_with_embedded_nul_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_suspicious_enum_usage_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_suspicious_include_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_suspicious_memset_usage_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_suspicious_missing_comma_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_suspicious_semicolon_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_suspicious_string_compare_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_swapped_arguments_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_terminating_continue_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_throw_keyword_missing_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_too_small_loop_variable_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_undefined_memory_manipulation_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_undelegated_constructor_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_unhandled_exception_at_new_highlighting=none
-resharper_cpp_clang_tidy_bugprone_unhandled_self_assignment_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_unused_raii_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_unused_return_value_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_use_after_move_highlighting=warning
-resharper_cpp_clang_tidy_bugprone_virtual_near_miss_highlighting=suggestion
-resharper_cpp_clang_tidy_cert_con36_c_highlighting=none
-resharper_cpp_clang_tidy_cert_con54_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl03_c_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl16_c_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl21_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl37_c_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl50_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl51_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl54_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_dcl58_cpp_highlighting=warning
-resharper_cpp_clang_tidy_cert_dcl59_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_env33_c_highlighting=none
-resharper_cpp_clang_tidy_cert_err09_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_err34_c_highlighting=suggestion
-resharper_cpp_clang_tidy_cert_err52_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_err58_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_err60_cpp_highlighting=warning
-resharper_cpp_clang_tidy_cert_err61_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_fio38_c_highlighting=none
-resharper_cpp_clang_tidy_cert_flp30_c_highlighting=warning
-resharper_cpp_clang_tidy_cert_mem57_cpp_highlighting=warning
-resharper_cpp_clang_tidy_cert_msc30_c_highlighting=none
-resharper_cpp_clang_tidy_cert_msc32_c_highlighting=none
-resharper_cpp_clang_tidy_cert_msc50_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_msc51_cpp_highlighting=warning
-resharper_cpp_clang_tidy_cert_oop11_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_oop54_cpp_highlighting=none
-resharper_cpp_clang_tidy_cert_oop57_cpp_highlighting=warning
-resharper_cpp_clang_tidy_cert_oop58_cpp_highlighting=warning
-resharper_cpp_clang_tidy_cert_pos44_c_highlighting=none
-resharper_cpp_clang_tidy_cert_pos47_c_highlighting=none
-resharper_cpp_clang_tidy_cert_sig30_c_highlighting=none
-resharper_cpp_clang_tidy_cert_str34_c_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_api_modeling_google_g_test_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_api_modeling_llvm_cast_value_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_api_modeling_llvm_return_value_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_api_modeling_std_c_library_functions_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_api_modeling_trust_nonnull_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_builtin_builtin_functions_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_builtin_no_return_functions_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_call_and_message_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_call_and_message_modeling_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_divide_zero_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_dynamic_type_propagation_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_nonnil_string_constants_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_non_null_param_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_null_dereference_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_stack_address_escape_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_stack_addr_escape_base_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_undefined_binary_operator_result_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_uninitialized_array_subscript_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_uninitialized_assign_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_uninitialized_branch_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_uninitialized_captured_block_variable_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_uninitialized_undef_return_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_core_vla_size_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_inner_pointer_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_move_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_new_delete_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_new_delete_leaks_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_placement_new_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_pure_virtual_call_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_self_assignment_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_smart_ptr_modeling_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_cplusplus_virtual_call_modeling_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_deadcode_dead_stores_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_fuchsia_handle_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_nullability_nullability_base_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_nullability_nullable_dereferenced_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_nullability_nullable_passed_to_nonnull_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_nullability_nullable_returned_from_nonnull_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_nullability_null_passed_to_nonnull_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_nullability_null_returned_from_nonnull_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_cplusplus_uninitialized_object_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_cplusplus_virtual_call_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_mpi_mpi_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_osx_cocoa_localizability_empty_localization_context_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_osx_cocoa_localizability_non_localized_string_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_osx_os_object_c_style_cast_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_performance_gcd_antipattern_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_performance_padding_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_optin_portability_unix_api_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_api_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_at_sync_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_autorelease_write_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_class_release_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_dealloc_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_incompatible_method_types_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_loops_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_missing_super_call_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_nil_arg_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_non_nil_return_value_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_ns_autorelease_pool_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_ns_error_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_obj_c_generics_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_retain_count_base_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_retain_count_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_run_loop_autorelease_leak_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_self_init_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_super_dealloc_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_unused_ivars_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_cocoa_variadic_method_types_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_core_foundation_cf_error_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_core_foundation_cf_number_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_core_foundation_cf_retain_release_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_core_foundation_containers_out_of_bounds_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_core_foundation_containers_pointer_sized_values_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_mig_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_ns_or_cf_error_deref_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_number_object_conversion_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_obj_c_property_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_os_object_retain_count_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_osx_sec_keychain_api_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_float_loop_counter_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_bcmp_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_bcopy_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_bzero_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_decode_value_of_obj_c_type_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_deprecated_or_unsafe_buffer_handling_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_getpw_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_gets_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_mkstemp_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_mktemp_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_rand_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_security_syntax_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_strcpy_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_unchecked_return_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_security_insecure_api_vfork_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_api_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_cstring_bad_size_arg_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_cstring_c_string_modeling_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_cstring_null_arg_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_dynamic_memory_modeling_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_malloc_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_malloc_sizeof_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_mismatched_deallocator_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_unix_vfork_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_valist_copy_to_self_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_valist_uninitialized_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_valist_unterminated_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_valist_valist_base_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_webkit_no_uncounted_member_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_webkit_ref_cntbl_base_virtual_dtor_highlighting=none
-resharper_cpp_clang_tidy_clang_analyzer_webkit_uncounted_lambda_captures_checker_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_absolute_value_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_abstract_final_class_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_abstract_vbase_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_address_of_packed_member_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_address_of_temporary_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_aix_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_align_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_alloca_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_alloca_with_align_alignof_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ambiguous_delete_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ambiguous_ellipsis_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ambiguous_macro_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ambiguous_member_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ambiguous_reversed_operator_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_analyzer_incompatible_plugin_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_anonymous_pack_parens_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_anon_enum_enum_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_bridge_casts_disallowed_in_nonarc_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_maybe_repeated_use_of_weak_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_non_pod_memaccess_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_perform_selector_leaks_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_repeated_use_of_weak_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_retain_cycles_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_arc_unsafe_retained_assign_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_argument_outside_range_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_array_bounds_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_array_bounds_pointer_arithmetic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_asm_operand_widths_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_assign_enum_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_assume_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_atimport_in_framework_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_atomic_alignment_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_atomic_implicit_seq_cst_highlighting=suggestion
-resharper_cpp_clang_tidy_clang_diagnostic_atomic_memory_ordering_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_atomic_property_with_user_defined_accessor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_attribute_packed_for_bitfield_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_at_protocol_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_auto_disable_vptr_sanitizer_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_auto_import_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_auto_storage_class_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_auto_var_id_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_availability_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_avr_rtlib_linking_quirks_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_backslash_newline_escape_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bad_function_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_binding_in_condition_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bind_to_temporary_copy_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bitfield_constant_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bitfield_enum_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bitfield_width_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bitwise_conditional_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bitwise_op_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_block_capture_autoreleasing_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bool_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bool_operation_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_braced_scalar_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_bridge_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_builtin_assume_aligned_alignment_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_builtin_macro_redefined_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_builtin_memcpy_chk_size_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_builtin_requires_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_c11_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_c2x_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_c99_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_c99_designator_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_c99_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_called_once_parameter_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_call_to_pure_virtual_from_ctor_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cast_align_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cast_calling_convention_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cast_function_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cast_of_sel_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cast_qual_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cast_qual_unrelated_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cf_string_literal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_char_subscripts_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_clang_cl_pch_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_class_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_class_varargs_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cmse_union_leak_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_comma_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_comment_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_compare_distinct_pointer_types_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_completion_handler_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_complex_component_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_compound_token_split_by_macro_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_compound_token_split_by_space_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_compound_token_split_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_concepts_ts_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_conditional_type_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_conditional_uninitialized_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_config_macros_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_constant_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_constant_evaluated_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_constant_logical_operand_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_constexpr_not_const_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_consumed_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_coroutine_missing_unhandled_exception_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_covered_switch_default_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_compat_deprecated_writable_strings_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_compat_reserved_user_defined_literal_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_extra_semi_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_inline_namespace_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_long_long_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp11_narrowing_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp14_binary_literal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp14_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp14_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp14_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp17_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp17_compat_mangling_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp17_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp17_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp20_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp20_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp20_designator_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp20_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp2a_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp2a_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp2b_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_compat_bind_to_temporary_copy_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_compat_extra_semi_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_compat_local_type_template_args_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_compat_unnamed_type_template_args_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_compat_binary_literal_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_cpp14_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_cpp14_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_cpp14_cpp17_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp98_cpp11_cpp14_cpp17_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cpp_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cstring_format_directive_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ctad_maybe_unsupported_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_ctu_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_cuda_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_custom_atomic_properties_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_cxx_attribute_extension_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dangling_else_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dangling_field_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dangling_gsl_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dangling_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dangling_initializer_list_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_darwin_sdk_settings_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_date_time_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dealloc_in_category_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_debug_compression_unavailable_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_declaration_after_statement_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_defaulted_function_deleted_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_delegating_ctor_cycles_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_delete_abstract_non_virtual_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_delete_incomplete_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_delete_non_abstract_non_virtual_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_delete_non_virtual_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_altivec_src_compat_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_anon_enum_enum_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_array_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_attributes_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_comma_subscript_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_copy_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_copy_with_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_copy_with_user_provided_copy_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_copy_with_user_provided_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_declarations_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_dynamic_exception_spec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_enum_compare_conditional_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_enum_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_enum_enum_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_enum_float_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_implementations_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_increment_bool_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_objc_isa_usage_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_objc_pointer_introspection_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_objc_pointer_introspection_perform_selector_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_register_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_this_capture_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_deprecated_volatile_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_direct_ivar_access_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_disabled_macro_expansion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_distributed_object_modifiers_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_division_by_zero_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dllexport_explicit_instantiation_decl_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dllimport_static_field_def_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dll_attribute_on_redeclaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_documentation_deprecated_sync_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_documentation_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_documentation_html_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_documentation_pedantic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_documentation_unknown_command_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_dollar_in_identifier_extension_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_double_promotion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dtor_name_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dtor_typedef_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_duplicate_decl_specifier_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_duplicate_enum_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_duplicate_method_arg_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_duplicate_method_match_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_duplicate_protocol_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dynamic_class_memaccess_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_dynamic_exception_spec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_embedded_directive_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_empty_body_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_empty_decomposition_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_empty_init_stmt_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_empty_translation_unit_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_encode_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_compare_conditional_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_compare_switch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_enum_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_float_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_enum_too_large_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_error_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_exceptions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_excess_initializers_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_exit_time_destructors_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_expansion_to_defined_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_explicit_initialize_call_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_explicit_ownership_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_export_unnamed_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_export_using_directive_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_extern_c_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_extern_initializer_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_extra_qualification_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_extra_semi_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_extra_semi_stmt_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_extra_tokens_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_final_dtor_non_final_class_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_fixed_enum_extension_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_fixed_point_overflow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_flag_enum_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_flexible_array_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_float_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_float_equal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_float_overflow_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_float_zero_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_extra_args_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_insufficient_args_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_invalid_specifier_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_nonliteral_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_non_iso_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_pedantic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_security_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_type_confusion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_format_zero_length_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_fortify_source_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_for_loop_analysis_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_four_char_constants_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_framework_include_private_from_public_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_frame_address_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_frame_larger_than_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_free_nonheap_object_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_function_def_in_objc_container_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_function_multiversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gcc_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_global_constructors_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_global_isel_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_alignof_expression_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_anonymous_struct_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_array_member_paren_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_auto_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_binary_literal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_case_range_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_complex_integer_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_compound_literal_initializer_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_conditional_omitted_operand_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_designator_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_empty_initializer_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_empty_struct_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_flexible_array_initializer_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_flexible_array_union_member_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_folding_constant_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_imaginary_constant_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_include_next_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_inline_cpp_without_extern_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_label_as_value_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_redeclared_enum_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_statement_expression_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_static_float_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_string_literal_operator_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_union_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_variable_sized_type_not_at_end_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_gnu_zero_variadic_macro_arguments_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_header_guard_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_header_hygiene_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_hip_only_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_idiomatic_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_attributes_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_availability_without_sdk_settings_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_optimization_argument_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_pragmas_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_pragma_intrinsic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_pragma_optimize_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_ignored_qualifiers_highlighting=suggestion
-resharper_cpp_clang_tidy_clang_diagnostic_implicitly_unsigned_literal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_atomic_properties_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_const_int_float_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_conversion_floating_point_to_bool_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_exception_spec_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_fallthrough_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_fallthrough_per_function_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_fixed_point_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_float_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_function_declaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_int_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_int_float_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_int_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_implicit_retain_self_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_import_preprocessor_directive_pedantic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inaccessible_base_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_include_next_absolute_path_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_include_next_outside_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_exception_spec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_function_pointer_types_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_library_redeclaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_ms_struct_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_pointer_types_discards_qualifiers_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_pointer_types_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_property_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incompatible_sysroot_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incomplete_framework_module_declaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incomplete_implementation_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incomplete_module_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incomplete_setjmp_declaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_incomplete_umbrella_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inconsistent_dllimport_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inconsistent_missing_destructor_override_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inconsistent_missing_override_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_increment_bool_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_independent_class_attribute_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_infinite_recursion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_initializer_overrides_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_injected_class_name_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inline_asm_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inline_namespace_reopened_noninline_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_inline_new_delete_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_instantiation_after_specialization_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_integer_overflow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_interrupt_service_routine_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_int_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_int_in_bool_context_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_int_to_pointer_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_int_to_void_pointer_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_constexpr_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_iboutlet_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_initializer_from_system_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_ios_deployment_target_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_noreturn_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_no_builtin_names_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_offsetof_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_or_nonexistent_directory_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_partial_specialization_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_pp_token_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_source_encoding_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_invalid_token_paste_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_jump_seh_finally_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_keyword_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_keyword_macro_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_knr_promoted_parameter_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_language_extension_token_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_large_by_value_copy_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_literal_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_literal_range_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_local_type_template_args_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_logical_not_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_logical_op_parentheses_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_long_long_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_macro_redefined_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_main_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_main_return_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_malformed_warning_check_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_many_braces_around_scalar_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_max_tokens_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_max_unsigned_zero_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_memset_transposed_args_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_memsize_comparison_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_method_signatures_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_abstract_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_anon_tag_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_charize_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_comment_paste_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_const_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_cpp_macro_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_default_arg_redefinition_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_drectve_section_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_end_of_file_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_enum_forward_reference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_enum_value_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_exception_spec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_exists_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_explicit_constructor_call_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_extra_qualification_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_fixed_enum_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_flexible_array_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_goto_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_inaccessible_base_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_include_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_mutable_reference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_pure_definition_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_redeclare_static_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_sealed_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_static_assert_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_template_shadow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_union_member_reference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_unqualified_friend_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_using_decl_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_microsoft_void_pseudo_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_misleading_indentation_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_mismatched_new_delete_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_mismatched_parameter_types_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_mismatched_return_types_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_mismatched_tags_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_braces_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_constinit_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_declarations_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_exception_spec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_field_initializers_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_method_return_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_noescape_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_noreturn_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_prototypes_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_missing_prototype_for_cc_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_selector_name_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_sysroot_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_missing_variable_declarations_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_misspelled_assumption_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_modules_ambiguous_internal_linkage_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_modules_import_nested_redundant_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_module_conflict_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_module_file_config_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_module_file_extension_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_module_import_in_extern_c_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_msvc_not_found_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_multichar_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_multiple_move_vbase_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nested_anon_types_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_newline_eof_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_new_returns_null_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_noderef_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nonnull_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nonportable_include_path_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nonportable_system_include_path_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nonportable_vector_initialization_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nontrivial_memaccess_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_c_typedef_for_linkage_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_literal_null_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_modular_include_in_framework_module_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_modular_include_in_module_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_pod_varargs_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_power_of_two_alignment_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_non_virtual_dtor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nsconsumed_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nsreturns_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ns_object_attribute_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullability_completeness_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullability_completeness_on_arrays_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullability_declspec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullability_extension_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullability_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullability_inferred_on_nested_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_nullable_to_nonnull_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_null_arithmetic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_null_character_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_null_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_null_dereference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_null_pointer_arithmetic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_null_pointer_subtraction_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_odr_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_old_style_cast_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_opencl_unsupported_rgba_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_openmp51_extensions_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_openmp_clauses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_openmp_loop_form_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_openmp_mapping_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_openmp_target_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_option_ignored_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_ordered_compare_function_pointers_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_out_of_line_declaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_out_of_scope_function_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_overlength_strings_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_overloaded_shift_op_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_overloaded_virtual_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_override_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_override_module_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_overriding_method_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_overriding_t_option_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_over_aligned_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_packed_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_padded_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_parentheses_equality_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pass_failed_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pch_date_time_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pedantic_core_features_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pedantic_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pessimizing_move_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_arith_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_bool_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_integer_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_sign_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_to_enum_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_to_int_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pointer_type_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_poison_system_directories_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_potentially_evaluated_expression_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragmas_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragma_clang_attribute_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragma_messages_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragma_once_outside_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragma_pack_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragma_pack_suspicious_include_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pragma_system_header_outside_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_predefined_identifier_outside_function_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_pre_c2x_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_c2x_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp14_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp14_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp17_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp17_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp20_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp20_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp2b_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_cpp2b_compat_pedantic_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_pre_openmp51_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_private_extern_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_private_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_private_module_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_profile_instr_missing_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_profile_instr_out_of_date_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_profile_instr_unprofiled_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_property_access_dot_syntax_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_property_attribute_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_protocol_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_protocol_property_synthesis_ambiguity_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_psabi_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_qualified_void_return_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_quoted_include_in_framework_header_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_range_loop_analysis_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_range_loop_bind_reference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_range_loop_construct_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_readonly_iboutlet_property_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_receiver_expr_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_receiver_forward_class_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_redeclared_class_member_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_redundant_move_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_redundant_parens_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_register_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reinterpret_base_class_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reorder_ctor_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reorder_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reorder_init_list_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_requires_expression_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_requires_super_attribute_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reserved_identifier_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reserved_id_macro_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reserved_macro_identifier_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_reserved_user_defined_literal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_retained_language_linkage_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_return_stack_address_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_return_std_move_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_return_type_c_linkage_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_return_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_rewrite_not_bool_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_section_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_selector_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_selector_type_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_self_assign_field_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_self_assign_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_self_assign_overloaded_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_self_move_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_semicolon_before_method_body_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sentinel_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_serialized_diagnostics_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shadow_field_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shadow_field_in_constructor_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_shadow_field_in_constructor_modified_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_shadow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shadow_ivar_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shadow_uncaptured_local_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_shift_count_negative_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shift_count_overflow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shift_negative_value_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shift_op_parentheses_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shift_overflow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shift_sign_overflow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_shorten64_to32_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_signed_enum_bitfield_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_signed_unsigned_wchar_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sign_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sign_conversion_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_sizeof_array_argument_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sizeof_array_decay_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sizeof_array_div_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sizeof_pointer_div_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sizeof_pointer_memaccess_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_slash_u_filename_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_slh_asm_goto_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_sometimes_uninitialized_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_source_uses_openmp_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_spir_compat_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_static_float_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_static_inline_explicit_instantiation_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_static_in_inline_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_static_local_in_inline_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_static_self_init_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_stdlibcxx_not_found_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_strict_prototypes_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_strict_selector_match_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_string_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_string_concatenation_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_string_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_string_plus_char_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_string_plus_int_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_strlcpy_strlcat_size_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_strncat_size_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_suggest_destructor_override_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_suggest_override_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_super_class_method_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_suspicious_bzero_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_switch_bool_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_switch_enum_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_switch_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_sync_fetch_and_nand_semantics_changed_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_bitwise_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_constant_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_constant_in_range_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_constant_out_of_range_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_objc_bool_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_overlap_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_pointer_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_type_limit_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_undefined_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_unsigned_char_zero_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_unsigned_enum_zero_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_unsigned_zero_compare_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_tautological_value_range_compare_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_tentative_definition_incomplete_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_analysis_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_attributes_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_beta_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_negative_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_precise_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_reference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_thread_safety_verbose_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_trigraphs_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_typedef_redefinition_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_typename_missing_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_type_safety_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unable_to_open_stats_file_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unavailable_declarations_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undeclared_selector_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_bool_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_func_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_inline_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_internal_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_internal_type_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_reinterpret_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undefined_var_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undef_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_undef_prefix_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_underaligned_exception_object_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unevaluated_expression_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unguarded_availability_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unguarded_availability_new_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unicode_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unicode_homoglyph_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unicode_whitespace_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unicode_zero_width_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_uninitialized_const_reference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_uninitialized_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_argument_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_attributes_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_cuda_version_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_escape_sequence_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_pragmas_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_sanitizers_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unknown_warning_option_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unnamed_type_template_args_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unneeded_internal_declaration_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unneeded_member_function_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unreachable_code_break_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unreachable_code_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unreachable_code_loop_increment_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unreachable_code_return_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsequenced_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_abs_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_availability_guard_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_cb_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_dll_base_class_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_friend_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_gpopt_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_nan_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_target_opt_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unsupported_visibility_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unusable_partial_specialization_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_but_set_parameter_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unused_but_set_variable_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unused_comparison_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_const_variable_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_exception_parameter_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_function_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_getter_return_value_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_label_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_lambda_capture_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unused_local_typedef_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_macros_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_member_function_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_parameter_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unused_private_field_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_property_ivar_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_result_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_template_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_value_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_unused_variable_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_unused_volatile_lvalue_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_used_but_marked_unused_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_user_defined_literals_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_user_defined_warnings_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_varargs_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_variadic_macros_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_vector_conversion_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_vec_elem_size_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_vexing_parse_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_visibility_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_vla_extension_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_vla_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_void_pointer_to_enum_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_void_pointer_to_int_cast_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_void_ptr_dereference_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_warnings_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_wasm_exception_spec_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_weak_template_vtables_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_weak_vtables_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_writable_strings_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_xor_used_as_pow_highlighting=warning
-resharper_cpp_clang_tidy_clang_diagnostic_zero_as_null_pointer_constant_highlighting=none
-resharper_cpp_clang_tidy_clang_diagnostic_zero_length_array_highlighting=warning
-resharper_cpp_clang_tidy_concurrency_mt_unsafe_highlighting=warning
-resharper_cpp_clang_tidy_concurrency_thread_canceltype_asynchronous_highlighting=warning
-resharper_cpp_clang_tidy_cppcoreguidelines_avoid_c_arrays_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_avoid_goto_highlighting=warning
-resharper_cpp_clang_tidy_cppcoreguidelines_avoid_magic_numbers_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_avoid_non_const_global_variables_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_c_copy_assignment_signature_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_explicit_virtual_functions_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_init_variables_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_interfaces_global_init_highlighting=warning
-resharper_cpp_clang_tidy_cppcoreguidelines_macro_usage_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_narrowing_conversions_highlighting=warning
-resharper_cpp_clang_tidy_cppcoreguidelines_non_private_member_variables_in_classes_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_no_malloc_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_owning_memory_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_prefer_member_initializer_highlighting=suggestion
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_bounds_array_to_pointer_decay_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_bounds_constant_array_index_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_bounds_pointer_arithmetic_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_const_cast_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_cstyle_cast_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_member_init_highlighting=warning
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_reinterpret_cast_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_static_cast_downcast_highlighting=suggestion
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_union_access_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_pro_type_vararg_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_slicing_highlighting=none
-resharper_cpp_clang_tidy_cppcoreguidelines_special_member_functions_highlighting=suggestion
-resharper_cpp_clang_tidy_darwin_avoid_spinlock_highlighting=none
-resharper_cpp_clang_tidy_darwin_dispatch_once_nonstatic_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_default_arguments_calls_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_default_arguments_declarations_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_header_anon_namespaces_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_multiple_inheritance_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_overloaded_operator_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_statically_constructed_objects_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_trailing_return_highlighting=none
-resharper_cpp_clang_tidy_fuchsia_virtual_inheritance_highlighting=none
-resharper_cpp_clang_tidy_google_build_explicit_make_pair_highlighting=none
-resharper_cpp_clang_tidy_google_build_namespaces_highlighting=none
-resharper_cpp_clang_tidy_google_build_using_namespace_highlighting=none
-resharper_cpp_clang_tidy_google_default_arguments_highlighting=none
-resharper_cpp_clang_tidy_google_explicit_constructor_highlighting=none
-resharper_cpp_clang_tidy_google_global_names_in_headers_highlighting=none
-resharper_cpp_clang_tidy_google_objc_avoid_nsobject_new_highlighting=none
-resharper_cpp_clang_tidy_google_objc_avoid_throwing_exception_highlighting=none
-resharper_cpp_clang_tidy_google_objc_function_naming_highlighting=none
-resharper_cpp_clang_tidy_google_objc_global_variable_declaration_highlighting=none
-resharper_cpp_clang_tidy_google_readability_avoid_underscore_in_googletest_name_highlighting=none
-resharper_cpp_clang_tidy_google_readability_braces_around_statements_highlighting=none
-resharper_cpp_clang_tidy_google_readability_casting_highlighting=none
-resharper_cpp_clang_tidy_google_readability_function_size_highlighting=none
-resharper_cpp_clang_tidy_google_readability_namespace_comments_highlighting=none
-resharper_cpp_clang_tidy_google_readability_todo_highlighting=none
-resharper_cpp_clang_tidy_google_runtime_int_highlighting=none
-resharper_cpp_clang_tidy_google_runtime_operator_highlighting=warning
-resharper_cpp_clang_tidy_google_upgrade_googletest_case_highlighting=suggestion
-resharper_cpp_clang_tidy_hicpp_avoid_c_arrays_highlighting=none
-resharper_cpp_clang_tidy_hicpp_avoid_goto_highlighting=warning
-resharper_cpp_clang_tidy_hicpp_braces_around_statements_highlighting=none
-resharper_cpp_clang_tidy_hicpp_deprecated_headers_highlighting=none
-resharper_cpp_clang_tidy_hicpp_exception_baseclass_highlighting=suggestion
-resharper_cpp_clang_tidy_hicpp_explicit_conversions_highlighting=none
-resharper_cpp_clang_tidy_hicpp_function_size_highlighting=none
-resharper_cpp_clang_tidy_hicpp_invalid_access_moved_highlighting=none
-resharper_cpp_clang_tidy_hicpp_member_init_highlighting=none
-resharper_cpp_clang_tidy_hicpp_move_const_arg_highlighting=none
-resharper_cpp_clang_tidy_hicpp_multiway_paths_covered_highlighting=warning
-resharper_cpp_clang_tidy_hicpp_named_parameter_highlighting=none
-resharper_cpp_clang_tidy_hicpp_new_delete_operators_highlighting=none
-resharper_cpp_clang_tidy_hicpp_noexcept_move_highlighting=none
-resharper_cpp_clang_tidy_hicpp_no_array_decay_highlighting=none
-resharper_cpp_clang_tidy_hicpp_no_assembler_highlighting=none
-resharper_cpp_clang_tidy_hicpp_no_malloc_highlighting=none
-resharper_cpp_clang_tidy_hicpp_signed_bitwise_highlighting=none
-resharper_cpp_clang_tidy_hicpp_special_member_functions_highlighting=none
-resharper_cpp_clang_tidy_hicpp_static_assert_highlighting=none
-resharper_cpp_clang_tidy_hicpp_undelegated_constructor_highlighting=none
-resharper_cpp_clang_tidy_hicpp_uppercase_literal_suffix_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_auto_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_emplace_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_equals_default_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_equals_delete_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_noexcept_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_nullptr_highlighting=none
-resharper_cpp_clang_tidy_hicpp_use_override_highlighting=none
-resharper_cpp_clang_tidy_hicpp_vararg_highlighting=none
-resharper_cpp_clang_tidy_highlighting_highlighting=suggestion
-resharper_cpp_clang_tidy_linuxkernel_must_check_errs_highlighting=warning
-resharper_cpp_clang_tidy_llvmlibc_callee_namespace_highlighting=none
-resharper_cpp_clang_tidy_llvmlibc_implementation_in_namespace_highlighting=none
-resharper_cpp_clang_tidy_llvmlibc_restrict_system_libc_headers_highlighting=none
-resharper_cpp_clang_tidy_llvm_else_after_return_highlighting=none
-resharper_cpp_clang_tidy_llvm_header_guard_highlighting=none
-resharper_cpp_clang_tidy_llvm_include_order_highlighting=none
-resharper_cpp_clang_tidy_llvm_namespace_comment_highlighting=none
-resharper_cpp_clang_tidy_llvm_prefer_isa_or_dyn_cast_in_conditionals_highlighting=none
-resharper_cpp_clang_tidy_llvm_prefer_register_over_unsigned_highlighting=suggestion
-resharper_cpp_clang_tidy_llvm_qualified_auto_highlighting=none
-resharper_cpp_clang_tidy_llvm_twine_local_highlighting=none
-resharper_cpp_clang_tidy_misc_definitions_in_headers_highlighting=none
-resharper_cpp_clang_tidy_misc_misplaced_const_highlighting=warning
-resharper_cpp_clang_tidy_misc_new_delete_overloads_highlighting=warning
-resharper_cpp_clang_tidy_misc_non_copyable_objects_highlighting=warning
-resharper_cpp_clang_tidy_misc_non_private_member_variables_in_classes_highlighting=none
-resharper_cpp_clang_tidy_misc_no_recursion_highlighting=none
-resharper_cpp_clang_tidy_misc_redundant_expression_highlighting=warning
-resharper_cpp_clang_tidy_misc_static_assert_highlighting=suggestion
-resharper_cpp_clang_tidy_misc_throw_by_value_catch_by_reference_highlighting=warning
-resharper_cpp_clang_tidy_misc_unconventional_assign_operator_highlighting=warning
-resharper_cpp_clang_tidy_misc_uniqueptr_reset_release_highlighting=suggestion
-resharper_cpp_clang_tidy_misc_unused_alias_decls_highlighting=suggestion
-resharper_cpp_clang_tidy_misc_unused_parameters_highlighting=none
-resharper_cpp_clang_tidy_misc_unused_using_decls_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_avoid_bind_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_avoid_c_arrays_highlighting=none
-resharper_cpp_clang_tidy_modernize_concat_nested_namespaces_highlighting=none
-resharper_cpp_clang_tidy_modernize_deprecated_headers_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_deprecated_ios_base_aliases_highlighting=warning
-resharper_cpp_clang_tidy_modernize_loop_convert_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_make_shared_highlighting=none
-resharper_cpp_clang_tidy_modernize_make_unique_highlighting=none
-resharper_cpp_clang_tidy_modernize_pass_by_value_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_raw_string_literal_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_redundant_void_arg_highlighting=none
-resharper_cpp_clang_tidy_modernize_replace_auto_ptr_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_replace_disallow_copy_and_assign_macro_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_replace_random_shuffle_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_return_braced_init_list_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_shrink_to_fit_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_unary_static_assert_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_auto_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_bool_literals_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_default_member_init_highlighting=none
-resharper_cpp_clang_tidy_modernize_use_emplace_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_equals_default_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_equals_delete_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_nodiscard_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_noexcept_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_nullptr_highlighting=none
-resharper_cpp_clang_tidy_modernize_use_override_highlighting=none
-resharper_cpp_clang_tidy_modernize_use_trailing_return_type_highlighting=none
-resharper_cpp_clang_tidy_modernize_use_transparent_functors_highlighting=suggestion
-resharper_cpp_clang_tidy_modernize_use_uncaught_exceptions_highlighting=warning
-resharper_cpp_clang_tidy_modernize_use_using_highlighting=none
-resharper_cpp_clang_tidy_mpi_buffer_deref_highlighting=warning
-resharper_cpp_clang_tidy_mpi_type_mismatch_highlighting=warning
-resharper_cpp_clang_tidy_objc_avoid_nserror_init_highlighting=warning
-resharper_cpp_clang_tidy_objc_dealloc_in_category_highlighting=warning
-resharper_cpp_clang_tidy_objc_forbidden_subclassing_highlighting=warning
-resharper_cpp_clang_tidy_objc_missing_hash_highlighting=warning
-resharper_cpp_clang_tidy_objc_nsinvocation_argument_lifetime_highlighting=warning
-resharper_cpp_clang_tidy_objc_property_declaration_highlighting=warning
-resharper_cpp_clang_tidy_objc_super_self_highlighting=warning
-resharper_cpp_clang_tidy_openmp_exception_escape_highlighting=warning
-resharper_cpp_clang_tidy_openmp_use_default_none_highlighting=warning
-resharper_cpp_clang_tidy_performance_faster_string_find_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_for_range_copy_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_implicit_conversion_in_loop_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_inefficient_algorithm_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_inefficient_string_concatenation_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_inefficient_vector_operation_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_move_constructor_init_highlighting=warning
-resharper_cpp_clang_tidy_performance_move_const_arg_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_noexcept_move_constructor_highlighting=none
-resharper_cpp_clang_tidy_performance_no_automatic_move_highlighting=warning
-resharper_cpp_clang_tidy_performance_no_int_to_ptr_highlighting=warning
-resharper_cpp_clang_tidy_performance_trivially_destructible_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_type_promotion_in_math_fn_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_unnecessary_copy_initialization_highlighting=suggestion
-resharper_cpp_clang_tidy_performance_unnecessary_value_param_highlighting=suggestion
-resharper_cpp_clang_tidy_portability_restrict_system_includes_highlighting=none
-resharper_cpp_clang_tidy_portability_simd_intrinsics_highlighting=none
-resharper_cpp_clang_tidy_readability_avoid_const_params_in_decls_highlighting=none
-resharper_cpp_clang_tidy_readability_braces_around_statements_highlighting=none
-resharper_cpp_clang_tidy_readability_const_return_type_highlighting=none
-resharper_cpp_clang_tidy_readability_container_size_empty_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_convert_member_functions_to_static_highlighting=none
-resharper_cpp_clang_tidy_readability_delete_null_pointer_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_else_after_return_highlighting=none
-resharper_cpp_clang_tidy_readability_function_cognitive_complexity_highlighting=none
-resharper_cpp_clang_tidy_readability_function_size_highlighting=none
-resharper_cpp_clang_tidy_readability_identifier_naming_highlighting=none
-resharper_cpp_clang_tidy_readability_implicit_bool_conversion_highlighting=none
-resharper_cpp_clang_tidy_readability_inconsistent_declaration_parameter_name_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_isolate_declaration_highlighting=none
-resharper_cpp_clang_tidy_readability_magic_numbers_highlighting=none
-resharper_cpp_clang_tidy_readability_make_member_function_const_highlighting=none
-resharper_cpp_clang_tidy_readability_misleading_indentation_highlighting=none
-resharper_cpp_clang_tidy_readability_misplaced_array_index_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_named_parameter_highlighting=none
-resharper_cpp_clang_tidy_readability_non_const_parameter_highlighting=none
-resharper_cpp_clang_tidy_readability_qualified_auto_highlighting=none
-resharper_cpp_clang_tidy_readability_redundant_access_specifiers_highlighting=none
-resharper_cpp_clang_tidy_readability_redundant_control_flow_highlighting=none
-resharper_cpp_clang_tidy_readability_redundant_declaration_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_redundant_function_ptr_dereference_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_redundant_member_init_highlighting=none
-resharper_cpp_clang_tidy_readability_redundant_preprocessor_highlighting=warning
-resharper_cpp_clang_tidy_readability_redundant_smartptr_get_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_redundant_string_cstr_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_redundant_string_init_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_simplify_boolean_expr_highlighting=none
-resharper_cpp_clang_tidy_readability_simplify_subscript_expr_highlighting=warning
-resharper_cpp_clang_tidy_readability_static_accessed_through_instance_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_static_definition_in_anonymous_namespace_highlighting=none
-resharper_cpp_clang_tidy_readability_string_compare_highlighting=warning
-resharper_cpp_clang_tidy_readability_suspicious_call_argument_highlighting=warning
-resharper_cpp_clang_tidy_readability_uniqueptr_delete_release_highlighting=suggestion
-resharper_cpp_clang_tidy_readability_uppercase_literal_suffix_highlighting=none
-resharper_cpp_clang_tidy_readability_use_anyofallof_highlighting=suggestion
-resharper_cpp_clang_tidy_zircon_temporary_objects_highlighting=none
-resharper_cpp_class_can_be_final_highlighting=hint
-resharper_cpp_class_disallow_lazy_merging_highlighting=warning
-resharper_cpp_class_is_incomplete_highlighting=warning
-resharper_cpp_class_needs_constructor_because_of_uninitialized_member_highlighting=warning
-resharper_cpp_class_never_used_highlighting=warning
-resharper_cpp_compile_time_constant_can_be_replaced_with_boolean_constant_highlighting=suggestion
-resharper_cpp_const_parameter_in_declaration_highlighting=suggestion
-resharper_cpp_const_value_function_return_type_highlighting=suggestion
-resharper_cpp_coroutine_call_resolve_error_highlighting=warning
-resharper_cpp_cv_qualifier_can_not_be_applied_to_reference_highlighting=warning
-resharper_cpp_c_style_cast_highlighting=suggestion
-resharper_cpp_declaration_hides_local_highlighting=warning
-resharper_cpp_declaration_hides_uncaptured_local_highlighting=hint
-resharper_cpp_declaration_specifier_without_declarators_highlighting=warning
-resharper_cpp_declarator_disambiguated_as_function_highlighting=warning
-resharper_cpp_declarator_never_used_highlighting=warning
-resharper_cpp_declarator_used_before_initialization_highlighting=error
-resharper_cpp_defaulted_special_member_function_is_implicitly_deleted_highlighting=warning
-resharper_cpp_default_case_not_handled_in_switch_statement_highlighting=warning
-resharper_cpp_default_initialization_with_no_user_constructor_highlighting=warning
-resharper_cpp_default_is_used_as_identifier_highlighting=warning
-resharper_cpp_deleting_void_pointer_highlighting=warning
-resharper_cpp_dependent_template_without_template_keyword_highlighting=warning
-resharper_cpp_dependent_type_without_typename_keyword_highlighting=warning
-resharper_cpp_deprecated_entity_highlighting=warning
-resharper_cpp_deprecated_register_storage_class_specifier_highlighting=warning
-resharper_cpp_dereference_operator_limit_exceeded_highlighting=warning
-resharper_cpp_discarded_postfix_operator_result_highlighting=suggestion
-resharper_cpp_doxygen_syntax_error_highlighting=warning
-resharper_cpp_doxygen_undocumented_parameter_highlighting=suggestion
-resharper_cpp_doxygen_unresolved_reference_highlighting=warning
-resharper_cpp_empty_declaration_highlighting=warning
-resharper_cpp_enforce_cv_qualifiers_order_highlighting=none
-resharper_cpp_enforce_cv_qualifiers_placement_highlighting=none
-resharper_cpp_enforce_do_statement_braces_highlighting=none
-resharper_cpp_enforce_for_statement_braces_highlighting=none
-resharper_cpp_enforce_function_declaration_style_highlighting=none
-resharper_cpp_enforce_if_statement_braces_highlighting=none
-resharper_cpp_enforce_nested_namespaces_style_highlighting=hint
-resharper_cpp_enforce_overriding_destructor_style_highlighting=suggestion
-resharper_cpp_enforce_overriding_function_style_highlighting=suggestion
-resharper_cpp_enforce_type_alias_code_style_highlighting=none
-resharper_cpp_enforce_while_statement_braces_highlighting=none
-resharper_cpp_entity_assigned_but_no_read_highlighting=warning
-resharper_cpp_entity_used_only_in_unevaluated_context_highlighting=warning
-resharper_cpp_enumerator_never_used_highlighting=warning
-resharper_cpp_equal_operands_in_binary_expression_highlighting=warning
-resharper_cpp_explicit_specialization_in_non_namespace_scope_highlighting=warning
-resharper_cpp_expression_without_side_effects_highlighting=warning
-resharper_cpp_final_function_in_final_class_highlighting=suggestion
-resharper_cpp_final_non_overriding_virtual_function_highlighting=suggestion
-resharper_cpp_for_loop_can_be_replaced_with_while_highlighting=suggestion
-resharper_cpp_functional_style_cast_highlighting=suggestion
-resharper_cpp_function_doesnt_return_value_highlighting=warning
-resharper_cpp_function_is_not_implemented_highlighting=warning
-resharper_cpp_header_has_been_already_included_highlighting=hint
-resharper_cpp_hidden_function_highlighting=warning
-resharper_cpp_hiding_function_highlighting=warning
-resharper_cpp_identical_operands_in_binary_expression_highlighting=warning
-resharper_cpp_if_can_be_replaced_by_constexpr_if_highlighting=suggestion
-resharper_cpp_implicit_default_constructor_not_available_highlighting=warning
-resharper_cpp_incompatible_pointer_conversion_highlighting=warning
-resharper_cpp_incomplete_switch_statement_highlighting=warning
-resharper_cpp_inconsistent_naming_highlighting=hint
-resharper_cpp_incorrect_blank_lines_near_braces_highlighting=none
-resharper_cpp_initialized_value_is_always_rewritten_highlighting=warning
-resharper_cpp_integral_to_pointer_conversion_highlighting=warning
-resharper_cpp_invalid_line_continuation_highlighting=warning
-resharper_cpp_join_declaration_and_assignment_highlighting=suggestion
-resharper_cpp_lambda_capture_never_used_highlighting=warning
-resharper_cpp_local_variable_may_be_const_highlighting=suggestion
-resharper_cpp_local_variable_might_not_be_initialized_highlighting=warning
-resharper_cpp_local_variable_with_non_trivial_dtor_is_never_used_highlighting=none
-resharper_cpp_long_float_highlighting=warning
-resharper_cpp_member_function_may_be_const_highlighting=suggestion
-resharper_cpp_member_function_may_be_static_highlighting=suggestion
-resharper_cpp_member_initializers_order_highlighting=suggestion
-resharper_cpp_mismatched_class_tags_highlighting=warning
-resharper_cpp_missing_blank_lines_highlighting=none
-resharper_cpp_missing_include_guard_highlighting=warning
-resharper_cpp_missing_indent_highlighting=none
-resharper_cpp_missing_keyword_throw_highlighting=warning
-resharper_cpp_missing_linebreak_highlighting=none
-resharper_cpp_missing_space_highlighting=none
-resharper_cpp_ms_ext_address_of_class_r_value_highlighting=warning
-resharper_cpp_ms_ext_binding_r_value_to_lvalue_reference_highlighting=warning
-resharper_cpp_ms_ext_copy_elision_in_copy_init_declarator_highlighting=warning
-resharper_cpp_ms_ext_double_user_conversion_in_copy_init_highlighting=warning
-resharper_cpp_ms_ext_not_initialized_static_const_local_var_highlighting=warning
-resharper_cpp_ms_ext_reinterpret_cast_from_nullptr_highlighting=warning
-resharper_cpp_multiple_spaces_highlighting=none
-resharper_cpp_must_be_public_virtual_to_implement_interface_highlighting=warning
-resharper_cpp_mutable_specifier_on_reference_member_highlighting=warning
-resharper_cpp_nodiscard_function_without_return_value_highlighting=warning
-resharper_cpp_non_exception_safe_resource_acquisition_highlighting=hint
-resharper_cpp_non_explicit_conversion_operator_highlighting=hint
-resharper_cpp_non_explicit_converting_constructor_highlighting=hint
-resharper_cpp_non_inline_function_definition_in_header_file_highlighting=warning
-resharper_cpp_non_inline_variable_definition_in_header_file_highlighting=warning
-resharper_cpp_not_all_paths_return_value_highlighting=warning
-resharper_cpp_no_discard_expression_highlighting=warning
-resharper_cpp_object_member_might_not_be_initialized_highlighting=warning
-resharper_cpp_outdent_is_off_prev_level_highlighting=none
-resharper_cpp_out_parameter_must_be_written_highlighting=warning
-resharper_cpp_parameter_may_be_const_highlighting=hint
-resharper_cpp_parameter_may_be_const_ptr_or_ref_highlighting=suggestion
-resharper_cpp_parameter_names_mismatch_highlighting=hint
-resharper_cpp_parameter_never_used_highlighting=hint
-resharper_cpp_parameter_value_is_reassigned_highlighting=warning
-resharper_cpp_pointer_conversion_drops_qualifiers_highlighting=warning
-resharper_cpp_pointer_to_integral_conversion_highlighting=warning
-resharper_cpp_polymorphic_class_with_non_virtual_public_destructor_highlighting=warning
-resharper_cpp_possibly_erroneous_empty_statements_highlighting=warning
-resharper_cpp_possibly_uninitialized_member_highlighting=warning
-resharper_cpp_possibly_unintended_object_slicing_highlighting=warning
-resharper_cpp_precompiled_header_is_not_included_highlighting=error
-resharper_cpp_precompiled_header_not_found_highlighting=error
-resharper_cpp_printf_bad_format_highlighting=warning
-resharper_cpp_printf_extra_arg_highlighting=warning
-resharper_cpp_printf_missed_arg_highlighting=error
-resharper_cpp_printf_risky_format_highlighting=warning
-resharper_cpp_private_special_member_function_is_not_implemented_highlighting=warning
-resharper_cpp_range_based_for_incompatible_reference_highlighting=warning
-resharper_cpp_redefinition_of_default_argument_in_override_function_highlighting=warning
-resharper_cpp_redundant_access_specifier_highlighting=hint
-resharper_cpp_redundant_base_class_access_specifier_highlighting=hint
-resharper_cpp_redundant_blank_lines_highlighting=none
-resharper_cpp_redundant_boolean_expression_argument_highlighting=warning
-resharper_cpp_redundant_cast_expression_highlighting=hint
-resharper_cpp_redundant_const_specifier_highlighting=hint
-resharper_cpp_redundant_control_flow_jump_highlighting=hint
-resharper_cpp_redundant_elaborated_type_specifier_highlighting=hint
-resharper_cpp_redundant_else_keyword_highlighting=hint
-resharper_cpp_redundant_else_keyword_inside_compound_statement_highlighting=hint
-resharper_cpp_redundant_empty_declaration_highlighting=hint
-resharper_cpp_redundant_empty_statement_highlighting=hint
-resharper_cpp_redundant_explicit_template_arguments_highlighting=hint
-resharper_cpp_redundant_inline_specifier_highlighting=hint
-resharper_cpp_redundant_lambda_parameter_list_highlighting=hint
-resharper_cpp_redundant_linebreak_highlighting=none
-resharper_cpp_redundant_member_initializer_highlighting=suggestion
-resharper_cpp_redundant_namespace_definition_highlighting=suggestion
-resharper_cpp_redundant_parentheses_highlighting=hint
-resharper_cpp_redundant_qualifier_highlighting=hint
-resharper_cpp_redundant_space_highlighting=none
-resharper_cpp_redundant_static_specifier_on_member_allocation_function_highlighting=hint
-resharper_cpp_redundant_template_keyword_highlighting=warning
-resharper_cpp_redundant_typename_keyword_highlighting=warning
-resharper_cpp_redundant_void_argument_list_highlighting=suggestion
-resharper_cpp_reinterpret_cast_from_void_ptr_highlighting=suggestion
-resharper_cpp_remove_redundant_braces_highlighting=none
-resharper_cpp_replace_memset_with_zero_initialization_highlighting=suggestion
-resharper_cpp_replace_tie_with_structured_binding_highlighting=suggestion
-resharper_cpp_return_no_value_in_non_void_function_highlighting=warning
-resharper_cpp_smart_pointer_vs_make_function_highlighting=suggestion
-resharper_cpp_some_object_members_might_not_be_initialized_highlighting=warning
-resharper_cpp_special_function_without_noexcept_specification_highlighting=warning
-resharper_cpp_static_data_member_in_unnamed_struct_highlighting=warning
-resharper_cpp_static_specifier_on_anonymous_namespace_member_highlighting=suggestion
-resharper_cpp_string_literal_to_char_pointer_conversion_highlighting=warning
-resharper_cpp_syntax_warning_highlighting=warning
-resharper_cpp_tabs_and_spaces_mismatch_highlighting=none
-resharper_cpp_tabs_are_disallowed_highlighting=none
-resharper_cpp_tabs_outside_indent_highlighting=none
-resharper_cpp_template_parameter_shadowing_highlighting=warning
-resharper_cpp_this_arg_member_func_delegate_ctor_is_unsuported_by_dot_net_core_highlighting=none
-resharper_cpp_throw_expression_can_be_replaced_with_rethrow_highlighting=warning
-resharper_cpp_too_wide_scope_highlighting=suggestion
-resharper_cpp_too_wide_scope_init_statement_highlighting=hint
-resharper_cpp_type_alias_never_used_highlighting=warning
-resharper_cpp_ue4_blueprint_callable_function_may_be_const_highlighting=hint
-resharper_cpp_ue4_blueprint_callable_function_may_be_static_highlighting=hint
-resharper_cpp_ue4_coding_standard_naming_violation_warning_highlighting=hint
-resharper_cpp_ue4_coding_standard_u_class_naming_violation_error_highlighting=error
-resharper_cpp_ue4_probable_memory_issues_with_u_objects_in_container_highlighting=warning
-resharper_cpp_ue4_probable_memory_issues_with_u_object_highlighting=warning
-resharper_cpp_ue_blueprint_callable_function_unused_highlighting=warning
-resharper_cpp_ue_blueprint_implementable_event_not_implemented_highlighting=warning
-resharper_cpp_ue_incorrect_engine_directory_highlighting=error
-resharper_cpp_ue_non_existent_input_action_highlighting=warning
-resharper_cpp_ue_non_existent_input_axis_highlighting=warning
-resharper_cpp_ue_source_file_without_predefined_macros_highlighting=warning
-resharper_cpp_ue_source_file_without_standard_library_highlighting=error
-resharper_cpp_ue_version_file_doesnt_exist_highlighting=error
-resharper_cpp_uninitialized_dependent_base_class_highlighting=warning
-resharper_cpp_uninitialized_non_static_data_member_highlighting=warning
-resharper_cpp_union_member_of_reference_type_highlighting=warning
-resharper_cpp_unnamed_namespace_in_header_file_highlighting=warning
-resharper_cpp_unnecessary_whitespace_highlighting=none
-resharper_cpp_unreachable_code_highlighting=warning
-resharper_cpp_unsigned_zero_comparison_highlighting=warning
-resharper_cpp_unused_include_directive_highlighting=warning
-resharper_cpp_user_defined_literal_suffix_does_not_start_with_underscore_highlighting=warning
-resharper_cpp_use_algorithm_with_count_highlighting=suggestion
-resharper_cpp_use_associative_contains_highlighting=suggestion
-resharper_cpp_use_auto_for_numeric_highlighting=hint
-resharper_cpp_use_auto_highlighting=hint
-resharper_cpp_use_elements_view_highlighting=suggestion
-resharper_cpp_use_erase_algorithm_highlighting=suggestion
-resharper_cpp_use_familiar_template_syntax_for_generic_lambdas_highlighting=suggestion
-resharper_cpp_use_range_algorithm_highlighting=suggestion
-resharper_cpp_use_std_size_highlighting=suggestion
-resharper_cpp_use_structured_binding_highlighting=hint
-resharper_cpp_use_type_trait_alias_highlighting=suggestion
-resharper_cpp_using_result_of_assignment_as_condition_highlighting=warning
-resharper_cpp_u_function_macro_call_has_no_effect_highlighting=warning
-resharper_cpp_u_property_macro_call_has_no_effect_highlighting=warning
-resharper_cpp_variable_can_be_made_constexpr_highlighting=suggestion
-resharper_cpp_virtual_function_call_inside_ctor_highlighting=warning
-resharper_cpp_virtual_function_in_final_class_highlighting=warning
-resharper_cpp_volatile_parameter_in_declaration_highlighting=suggestion
-resharper_cpp_wrong_includes_order_highlighting=hint
-resharper_cpp_wrong_indent_size_highlighting=none
-resharper_cpp_wrong_slashes_in_include_directive_highlighting=hint
-resharper_cpp_zero_constant_can_be_replaced_with_nullptr_highlighting=suggestion
-resharper_cpp_zero_valued_expression_used_as_null_pointer_highlighting=warning
-resharper_create_specialized_overload_highlighting=hint
-resharper_css_browser_compatibility_highlighting=warning
-resharper_css_caniuse_feature_requires_prefix_highlighting=hint
-resharper_css_caniuse_unsupported_feature_highlighting=hint
-resharper_css_not_resolved_highlighting=error
-resharper_css_obsolete_highlighting=hint
-resharper_css_property_does_not_override_vendor_property_highlighting=warning
-resharper_cyclic_reference_comment_highlighting=none
-resharper_c_declaration_with_implicit_int_type_highlighting=warning
-resharper_c_sharp_build_cs_invalid_module_name_highlighting=warning
-resharper_c_sharp_missing_plugin_dependency_highlighting=warning
-resharper_declaration_hides_highlighting=hint
-resharper_declaration_is_empty_highlighting=warning
-resharper_declaration_visibility_error_highlighting=error
-resharper_default_value_attribute_for_optional_parameter_highlighting=warning
-resharper_deleting_non_qualified_reference_highlighting=error
-resharper_dl_tag_contains_non_dt_or_dd_elements_highlighting=hint
-resharper_double_colons_expected_highlighting=error
-resharper_double_colons_preferred_highlighting=suggestion
-resharper_double_negation_in_pattern_highlighting=suggestion
-resharper_double_negation_of_boolean_highlighting=warning
-resharper_double_negation_operator_highlighting=suggestion
-resharper_duplicate_identifier_error_highlighting=error
-resharper_duplicate_reference_comment_highlighting=warning
-resharper_duplicate_resource_highlighting=warning
-resharper_duplicating_local_declaration_highlighting=warning
-resharper_duplicating_parameter_declaration_error_highlighting=error
-resharper_duplicating_property_declaration_error_highlighting=error
-resharper_duplicating_property_declaration_highlighting=warning
-resharper_duplicating_switch_label_highlighting=warning
-resharper_dynamic_shift_right_op_is_not_int_highlighting=warning
-resharper_elided_trailing_element_highlighting=warning
-resharper_empty_constructor_highlighting=warning
-resharper_empty_destructor_highlighting=warning
-resharper_empty_embedded_statement_highlighting=warning
-resharper_empty_for_statement_highlighting=warning
-resharper_empty_general_catch_clause_highlighting=warning
-resharper_empty_namespace_highlighting=warning
-resharper_empty_object_property_declaration_highlighting=error
-resharper_empty_return_value_for_type_annotated_function_highlighting=warning
-resharper_empty_statement_highlighting=warning
-resharper_empty_title_tag_highlighting=hint
-resharper_enforce_do_while_statement_braces_highlighting=none
-resharper_enforce_fixed_statement_braces_highlighting=none
-resharper_enforce_foreach_statement_braces_highlighting=none
-resharper_enforce_for_statement_braces_highlighting=none
-resharper_enforce_if_statement_braces_highlighting=none
-resharper_enforce_lock_statement_braces_highlighting=none
-resharper_enforce_using_statement_braces_highlighting=none
-resharper_enforce_while_statement_braces_highlighting=none
-resharper_entity_name_captured_only_global_highlighting=warning
-resharper_entity_name_captured_only_local_highlighting=warning
-resharper_enumerable_sum_in_explicit_unchecked_context_highlighting=warning
-resharper_enum_underlying_type_is_int_highlighting=warning
-resharper_equal_expression_comparison_highlighting=warning
-resharper_error_in_xml_doc_reference_highlighting=error
-resharper_es6_feature_highlighting=error
-resharper_es7_feature_highlighting=error
-resharper_eval_arguments_name_error_highlighting=error
-resharper_event_never_invoked_global_highlighting=suggestion
-resharper_event_never_subscribed_to_global_highlighting=suggestion
-resharper_event_never_subscribed_to_local_highlighting=suggestion
-resharper_event_unsubscription_via_anonymous_delegate_highlighting=warning
-resharper_experimental_feature_highlighting=error
-resharper_explicit_caller_info_argument_highlighting=warning
-resharper_expression_is_always_const_highlighting=warning
-resharper_expression_is_always_null_highlighting=warning
-resharper_field_can_be_made_read_only_global_highlighting=suggestion
-resharper_field_can_be_made_read_only_local_highlighting=suggestion
-resharper_field_hides_interface_property_with_default_implementation_highlighting=warning
-resharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlighting=hint
-resharper_foreach_can_be_partly_converted_to_query_using_another_get_enumerator_highlighting=hint
-resharper_format_string_placeholders_mismatch_highlighting=warning
-resharper_format_string_problem_highlighting=warning
-resharper_for_can_be_converted_to_foreach_highlighting=suggestion
-resharper_for_statement_condition_is_true_highlighting=warning
-resharper_functions_used_before_declared_highlighting=none
-resharper_function_complexity_overflow_highlighting=none
-resharper_function_never_returns_highlighting=warning
-resharper_function_parameter_named_arguments_highlighting=warning
-resharper_function_recursive_on_all_paths_highlighting=warning
-resharper_function_used_out_of_scope_highlighting=warning
-resharper_gc_suppress_finalize_for_type_without_destructor_highlighting=warning
-resharper_generic_enumerator_not_disposed_highlighting=warning
-resharper_heuristically_unreachable_code_highlighting=warning
-resharper_heuristic_unreachable_code_highlighting=warning
-resharper_hex_color_value_with_alpha_highlighting=error
-resharper_html_attributes_quotes_highlighting=hint
-resharper_html_attribute_not_resolved_highlighting=warning
-resharper_html_attribute_value_not_resolved_highlighting=warning
-resharper_html_dead_code_highlighting=warning
-resharper_html_event_not_resolved_highlighting=warning
-resharper_html_id_duplication_highlighting=warning
-resharper_html_id_not_resolved_highlighting=warning
-resharper_html_obsolete_highlighting=warning
-resharper_html_path_error_highlighting=warning
-resharper_html_tag_not_closed_highlighting=error
-resharper_html_tag_not_resolved_highlighting=warning
-resharper_html_tag_should_be_self_closed_highlighting=warning
-resharper_html_tag_should_not_be_self_closed_highlighting=warning
-resharper_html_warning_highlighting=warning
-resharper_identifier_typo_highlighting=suggestion
-resharper_implicit_any_error_highlighting=error
-resharper_implicit_any_type_warning_highlighting=warning
-resharper_import_keyword_not_with_invocation_highlighting=error
-resharper_inactive_preprocessor_branch_highlighting=warning
-resharper_inconsistently_synchronized_field_highlighting=warning
-resharper_inconsistent_function_returns_highlighting=warning
-resharper_inconsistent_naming_highlighting=warning
-resharper_inconsistent_order_of_locks_highlighting=warning
-resharper_incorrect_blank_lines_near_braces_highlighting=none
-resharper_incorrect_operand_in_type_of_comparison_highlighting=warning
-resharper_incorrect_triple_slash_location_highlighting=warning
-resharper_indexing_by_invalid_range_highlighting=warning
-resharper_inheritdoc_consider_usage_highlighting=none
-resharper_inheritdoc_invalid_usage_highlighting=warning
-resharper_inline_out_variable_declaration_highlighting=suggestion
-resharper_inline_temporary_variable_highlighting=hint
-resharper_internal_module_highlighting=suggestion
-resharper_internal_or_private_member_not_documented_highlighting=none
-resharper_interpolated_string_expression_is_not_i_formattable_highlighting=warning
-resharper_introduce_optional_parameters_global_highlighting=suggestion
-resharper_introduce_optional_parameters_local_highlighting=suggestion
-resharper_introduce_variable_to_apply_guard_highlighting=hint
-resharper_int_division_by_zero_highlighting=warning
-resharper_int_variable_overflow_highlighting=warning
-resharper_int_variable_overflow_in_checked_context_highlighting=warning
-resharper_int_variable_overflow_in_unchecked_context_highlighting=warning
-resharper_invalid_attribute_value_highlighting=warning
-resharper_invalid_json_syntax_highlighting=error
-resharper_invalid_task_element_highlighting=none
-resharper_invalid_value_highlighting=error
-resharper_invalid_value_type_highlighting=warning
-resharper_invalid_xml_doc_comment_highlighting=warning
-resharper_invert_condition_1_highlighting=hint
-resharper_invert_if_highlighting=hint
-resharper_invocation_is_skipped_highlighting=hint
-resharper_invocation_of_non_function_highlighting=warning
-resharper_invoked_expression_maybe_non_function_highlighting=warning
-resharper_invoke_as_extension_method_highlighting=suggestion
-resharper_is_expression_always_false_highlighting=warning
-resharper_is_expression_always_true_highlighting=warning
-resharper_iterator_method_result_is_ignored_highlighting=warning
-resharper_iterator_never_returns_highlighting=warning
-resharper_join_declaration_and_initializer_highlighting=suggestion
-resharper_join_declaration_and_initializer_js_highlighting=suggestion
-resharper_join_null_check_with_usage_highlighting=suggestion
-resharper_join_null_check_with_usage_when_possible_highlighting=none
-resharper_json_validation_failed_highlighting=error
-resharper_js_path_not_found_highlighting=error
-resharper_js_unreachable_code_highlighting=warning
-resharper_jump_must_be_in_loop_highlighting=warning
-resharper_label_or_semicolon_expected_highlighting=error
-resharper_lambda_expression_can_be_made_static_highlighting=none
-resharper_lambda_expression_must_be_static_highlighting=suggestion
-resharper_lambda_highlighting=suggestion
-resharper_lambda_should_not_capture_context_highlighting=warning
-resharper_less_specific_overload_than_main_signature_highlighting=warning
-resharper_lexical_declaration_needs_block_highlighting=error
-resharper_localizable_element_highlighting=warning
-resharper_local_function_can_be_made_static_highlighting=none
-resharper_local_function_hides_method_highlighting=warning
-resharper_local_function_redefined_later_highlighting=warning
-resharper_local_variable_hides_member_highlighting=warning
-resharper_long_literal_ending_lower_l_highlighting=warning
-resharper_loop_can_be_converted_to_query_highlighting=hint
-resharper_loop_can_be_partly_converted_to_query_highlighting=none
-resharper_loop_variable_is_never_changed_inside_loop_highlighting=warning
-resharper_l_value_is_expected_highlighting=error
-resharper_markup_attribute_typo_highlighting=suggestion
-resharper_markup_text_typo_highlighting=suggestion
-resharper_math_abs_method_is_redundant_highlighting=warning
-resharper_math_clamp_min_greater_than_max_highlighting=warning
-resharper_meaningless_default_parameter_value_highlighting=warning
-resharper_member_can_be_internal_highlighting=none
-resharper_member_can_be_made_static_global_highlighting=hint
-resharper_member_can_be_made_static_local_highlighting=hint
-resharper_member_can_be_private_global_highlighting=suggestion
-resharper_member_can_be_private_local_highlighting=suggestion
-resharper_member_can_be_protected_global_highlighting=suggestion
-resharper_member_can_be_protected_local_highlighting=suggestion
-resharper_member_hides_interface_member_with_default_implementation_highlighting=warning
-resharper_member_hides_static_from_outer_class_highlighting=warning
-resharper_member_initializer_value_ignored_highlighting=warning
-resharper_merge_and_pattern_highlighting=suggestion
-resharper_merge_cast_with_type_check_highlighting=suggestion
-resharper_merge_conditional_expression_highlighting=suggestion
-resharper_merge_conditional_expression_when_possible_highlighting=none
-resharper_merge_into_logical_pattern_highlighting=hint
-resharper_merge_into_negated_pattern_highlighting=hint
-resharper_merge_into_pattern_highlighting=suggestion
-resharper_merge_nested_property_patterns_highlighting=suggestion
-resharper_merge_sequential_checks_highlighting=hint
-resharper_merge_sequential_checks_when_possible_highlighting=none
-resharper_method_has_async_overload_highlighting=suggestion
-resharper_method_has_async_overload_with_cancellation_highlighting=suggestion
-resharper_method_overload_with_optional_parameter_highlighting=warning
-resharper_method_safe_this_highlighting=suggestion
-resharper_method_supports_cancellation_highlighting=suggestion
-resharper_missing_alt_attribute_in_img_tag_highlighting=hint
-resharper_missing_attribute_highlighting=warning
-resharper_missing_blank_lines_highlighting=none
-resharper_missing_body_tag_highlighting=warning
-resharper_missing_has_own_property_in_foreach_highlighting=warning
-resharper_missing_head_and_body_tags_highlighting=warning
-resharper_missing_head_tag_highlighting=warning
-resharper_missing_indent_highlighting=none
-resharper_missing_linebreak_highlighting=none
-resharper_missing_space_highlighting=none
-resharper_missing_title_tag_highlighting=hint
-resharper_misuse_of_owner_function_this_highlighting=warning
-resharper_more_specific_foreach_variable_type_available_highlighting=suggestion
-resharper_more_specific_signature_after_less_specific_highlighting=warning
-resharper_move_to_existing_positional_deconstruction_pattern_highlighting=hint
-resharper_multiple_declarations_in_foreach_highlighting=error
-resharper_multiple_nullable_attributes_usage_highlighting=warning
-resharper_multiple_order_by_highlighting=warning
-resharper_multiple_output_tags_highlighting=warning
-resharper_multiple_resolve_candidates_in_text_highlighting=warning
-resharper_multiple_spaces_highlighting=none
-resharper_multiple_statements_on_one_line_highlighting=none
-resharper_multiple_type_members_on_one_line_highlighting=none
-resharper_must_use_return_value_highlighting=warning
-resharper_mvc_action_not_resolved_highlighting=error
-resharper_mvc_area_not_resolved_highlighting=error
-resharper_mvc_controller_not_resolved_highlighting=error
-resharper_mvc_invalid_model_type_highlighting=error
-resharper_mvc_masterpage_not_resolved_highlighting=error
-resharper_mvc_partial_view_not_resolved_highlighting=error
-resharper_mvc_template_not_resolved_highlighting=error
-resharper_mvc_view_component_not_resolved_highlighting=error
-resharper_mvc_view_component_view_not_resolved_highlighting=error
-resharper_mvc_view_not_resolved_highlighting=error
-resharper_native_type_prototype_extending_highlighting=warning
-resharper_native_type_prototype_overwriting_highlighting=warning
-resharper_negation_of_relational_pattern_highlighting=suggestion
-resharper_negative_equality_expression_highlighting=suggestion
-resharper_negative_index_highlighting=warning
-resharper_nested_string_interpolation_highlighting=suggestion
-resharper_non_assigned_constant_highlighting=error
-resharper_non_atomic_compound_operator_highlighting=warning
-resharper_non_constant_equality_expression_has_constant_result_highlighting=warning
-resharper_non_parsable_element_highlighting=warning
-resharper_non_readonly_member_in_get_hash_code_highlighting=warning
-resharper_non_volatile_field_in_double_check_locking_highlighting=warning
-resharper_not_accessed_field_global_highlighting=suggestion
-resharper_not_accessed_field_local_highlighting=warning
-resharper_not_accessed_positional_property_global_highlighting=warning
-resharper_not_accessed_positional_property_local_highlighting=warning
-resharper_not_accessed_variable_highlighting=warning
-resharper_not_all_paths_return_value_highlighting=warning
-resharper_not_assigned_out_parameter_highlighting=warning
-resharper_not_declared_in_parent_culture_highlighting=warning
-resharper_not_null_member_is_not_initialized_highlighting=warning
-resharper_not_observable_annotation_redundancy_highlighting=warning
-resharper_not_overridden_in_specific_culture_highlighting=warning
-resharper_not_resolved_highlighting=warning
-resharper_not_resolved_in_text_highlighting=warning
-resharper_nullable_warning_suppression_is_used_highlighting=none
-resharper_n_unit_async_method_must_be_task_highlighting=warning
-resharper_n_unit_attribute_produces_too_many_tests_highlighting=none
-resharper_n_unit_auto_fixture_incorrect_argument_type_highlighting=warning
-resharper_n_unit_auto_fixture_missed_test_attribute_highlighting=warning
-resharper_n_unit_auto_fixture_missed_test_or_test_fixture_attribute_highlighting=warning
-resharper_n_unit_auto_fixture_redundant_argument_in_inline_auto_data_attribute_highlighting=warning
-resharper_n_unit_duplicate_values_highlighting=warning
-resharper_n_unit_ignored_parameter_attribute_highlighting=warning
-resharper_n_unit_implicit_unspecified_null_values_highlighting=warning
-resharper_n_unit_incorrect_argument_type_highlighting=warning
-resharper_n_unit_incorrect_expected_result_type_highlighting=warning
-resharper_n_unit_incorrect_range_bounds_highlighting=warning
-resharper_n_unit_method_with_parameters_and_test_attribute_highlighting=warning
-resharper_n_unit_missing_arguments_in_test_case_attribute_highlighting=warning
-resharper_n_unit_non_public_method_with_test_attribute_highlighting=warning
-resharper_n_unit_no_values_provided_highlighting=warning
-resharper_n_unit_parameter_type_is_not_compatible_with_attribute_highlighting=warning
-resharper_n_unit_range_attribute_bounds_are_out_of_range_highlighting=warning
-resharper_n_unit_range_step_sign_mismatch_highlighting=warning
-resharper_n_unit_range_step_value_must_not_be_zero_highlighting=warning
-resharper_n_unit_range_to_value_is_not_reachable_highlighting=warning
-resharper_n_unit_redundant_argument_instead_of_expected_result_highlighting=warning
-resharper_n_unit_redundant_argument_in_test_case_attribute_highlighting=warning
-resharper_n_unit_redundant_expected_result_in_test_case_attribute_highlighting=warning
-resharper_n_unit_test_case_attribute_requires_expected_result_highlighting=warning
-resharper_n_unit_test_case_result_property_duplicates_expected_result_highlighting=warning
-resharper_n_unit_test_case_result_property_is_obsolete_highlighting=warning
-resharper_n_unit_test_case_source_cannot_be_resolved_highlighting=warning
-resharper_n_unit_test_case_source_must_be_field_property_method_highlighting=warning
-resharper_n_unit_test_case_source_must_be_static_highlighting=warning
-resharper_n_unit_test_case_source_should_implement_i_enumerable_highlighting=warning
-resharper_object_creation_as_statement_highlighting=warning
-resharper_object_destructuring_without_parentheses_highlighting=error
-resharper_object_literals_are_not_comma_free_highlighting=error
-resharper_obsolete_element_error_highlighting=error
-resharper_obsolete_element_highlighting=warning
-resharper_octal_literals_not_allowed_error_highlighting=error
-resharper_ol_tag_contains_non_li_elements_highlighting=hint
-resharper_one_way_operation_contract_with_return_type_highlighting=warning
-resharper_operation_contract_without_service_contract_highlighting=warning
-resharper_operator_is_can_be_used_highlighting=warning
-resharper_optional_parameter_hierarchy_mismatch_highlighting=warning
-resharper_optional_parameter_ref_out_highlighting=warning
-resharper_other_tags_inside_script1_highlighting=error
-resharper_other_tags_inside_script2_highlighting=error
-resharper_other_tags_inside_unclosed_script_highlighting=error
-resharper_outdent_is_off_prev_level_highlighting=none
-resharper_output_tag_required_highlighting=warning
-resharper_out_parameter_value_is_always_discarded_global_highlighting=suggestion
-resharper_out_parameter_value_is_always_discarded_local_highlighting=warning
-resharper_overload_signature_inferring_highlighting=hint
-resharper_overridden_with_empty_value_highlighting=warning
-resharper_overridden_with_same_value_highlighting=suggestion
-resharper_parameter_doesnt_make_any_sense_highlighting=warning
-resharper_parameter_hides_member_highlighting=warning
-resharper_parameter_only_used_for_precondition_check_global_highlighting=suggestion
-resharper_parameter_only_used_for_precondition_check_local_highlighting=warning
-resharper_parameter_type_can_be_enumerable_global_highlighting=hint
-resharper_parameter_type_can_be_enumerable_local_highlighting=hint
-resharper_parameter_value_is_not_used_highlighting=warning
-resharper_partial_method_parameter_name_mismatch_highlighting=warning
-resharper_partial_method_with_single_part_highlighting=warning
-resharper_partial_type_with_single_part_highlighting=warning
-resharper_pass_string_interpolation_highlighting=hint
-resharper_path_not_resolved_highlighting=error
-resharper_pattern_always_matches_highlighting=warning
-resharper_pattern_is_always_true_or_false_highlighting=warning
-resharper_pattern_never_matches_highlighting=warning
-resharper_polymorphic_field_like_event_invocation_highlighting=warning
-resharper_possible_infinite_inheritance_highlighting=warning
-resharper_possible_intended_rethrow_highlighting=warning
-resharper_possible_interface_member_ambiguity_highlighting=warning
-resharper_possible_invalid_cast_exception_highlighting=warning
-resharper_possible_invalid_cast_exception_in_foreach_loop_highlighting=warning
-resharper_possible_invalid_operation_exception_highlighting=warning
-resharper_possible_loss_of_fraction_highlighting=warning
-resharper_possible_mistaken_argument_highlighting=warning
-resharper_possible_mistaken_call_to_get_type_1_highlighting=warning
-resharper_possible_mistaken_call_to_get_type_2_highlighting=warning
-resharper_possible_multiple_enumeration_highlighting=warning
-resharper_possible_multiple_write_access_in_double_check_locking_highlighting=warning
-resharper_possible_null_reference_exception_highlighting=warning
-resharper_possible_struct_member_modification_of_non_variable_struct_highlighting=warning
-resharper_possible_unintended_linear_search_in_set_highlighting=warning
-resharper_possible_unintended_queryable_as_enumerable_highlighting=suggestion
-resharper_possible_unintended_reference_comparison_highlighting=warning
-resharper_possible_write_to_me_highlighting=warning
-resharper_possibly_impure_method_call_on_readonly_variable_highlighting=warning
-resharper_possibly_incorrectly_broken_statement_highlighting=warning
-resharper_possibly_missing_indexer_initializer_comma_highlighting=warning
-resharper_possibly_mistaken_use_of_interpolated_string_insert_highlighting=warning
-resharper_possibly_mistaken_use_of_params_method_highlighting=warning
-resharper_possibly_unassigned_property_highlighting=hint
-resharper_private_field_can_be_converted_to_local_variable_highlighting=warning
-resharper_private_variable_can_be_made_readonly_highlighting=hint
-resharper_property_can_be_made_init_only_global_highlighting=suggestion
-resharper_property_can_be_made_init_only_local_highlighting=suggestion
-resharper_property_getter_cannot_have_parameters_highlighting=error
-resharper_property_not_resolved_highlighting=error
-resharper_property_setter_must_have_single_parameter_highlighting=error
-resharper_public_constructor_in_abstract_class_highlighting=suggestion
-resharper_pure_attribute_on_void_method_highlighting=warning
-resharper_qualified_expression_is_null_highlighting=warning
-resharper_qualified_expression_maybe_null_highlighting=warning
-resharper_razor_layout_not_resolved_highlighting=error
-resharper_razor_section_not_resolved_highlighting=error
-resharper_read_access_in_double_check_locking_highlighting=warning
-resharper_redundant_abstract_modifier_highlighting=warning
-resharper_redundant_always_match_subpattern_highlighting=suggestion
-resharper_redundant_anonymous_type_property_name_highlighting=warning
-resharper_redundant_argument_default_value_highlighting=warning
-resharper_redundant_array_creation_expression_highlighting=hint
-resharper_redundant_array_lower_bound_specification_highlighting=warning
-resharper_redundant_assignment_highlighting=warning
-resharper_redundant_attribute_parentheses_highlighting=hint
-resharper_redundant_attribute_usage_property_highlighting=suggestion
-resharper_redundant_base_constructor_call_highlighting=warning
resharper_redundant_base_qualifier_highlighting=warning
-resharper_redundant_blank_lines_highlighting=none
-resharper_redundant_block_highlighting=warning
-resharper_redundant_bool_compare_highlighting=warning
-resharper_redundant_case_label_highlighting=warning
-resharper_redundant_cast_highlighting=warning
-resharper_redundant_catch_clause_highlighting=warning
-resharper_redundant_check_before_assignment_highlighting=warning
-resharper_redundant_collection_initializer_element_braces_highlighting=hint
-resharper_redundant_comparison_with_boolean_highlighting=warning
-resharper_redundant_configure_await_highlighting=suggestion
-resharper_redundant_css_hack_highlighting=warning
-resharper_redundant_declaration_semicolon_highlighting=hint
-resharper_redundant_default_member_initializer_highlighting=warning
-resharper_redundant_delegate_creation_highlighting=warning
-resharper_redundant_disable_warning_comment_highlighting=warning
-resharper_redundant_discard_designation_highlighting=suggestion
-resharper_redundant_else_block_highlighting=warning
-resharper_redundant_empty_case_else_highlighting=warning
-resharper_redundant_empty_constructor_highlighting=warning
-resharper_redundant_empty_finally_block_highlighting=warning
-resharper_redundant_empty_object_creation_argument_list_highlighting=hint
-resharper_redundant_empty_object_or_collection_initializer_highlighting=warning
-resharper_redundant_empty_switch_section_highlighting=warning
-resharper_redundant_enumerable_cast_call_highlighting=warning
-resharper_redundant_enum_case_label_for_default_section_highlighting=none
-resharper_redundant_explicit_array_creation_highlighting=warning
-resharper_redundant_explicit_array_size_highlighting=warning
-resharper_redundant_explicit_nullable_creation_highlighting=warning
-resharper_redundant_explicit_params_array_creation_highlighting=suggestion
-resharper_redundant_explicit_positional_property_declaration_highlighting=warning
-resharper_redundant_explicit_tuple_component_name_highlighting=warning
-resharper_redundant_extends_list_entry_highlighting=warning
-resharper_redundant_fixed_pointer_declaration_highlighting=suggestion
-resharper_redundant_highlighting=warning
-resharper_redundant_if_else_block_highlighting=hint
-resharper_redundant_if_statement_then_keyword_highlighting=none
-resharper_redundant_immediate_delegate_invocation_highlighting=suggestion
-resharper_redundant_intermediate_variable_highlighting=hint
-resharper_redundant_is_before_relational_pattern_highlighting=suggestion
-resharper_redundant_iterator_keyword_highlighting=warning
-resharper_redundant_jump_statement_highlighting=warning
-resharper_redundant_lambda_parameter_type_highlighting=warning
-resharper_redundant_lambda_signature_parentheses_highlighting=hint
-resharper_redundant_linebreak_highlighting=none
-resharper_redundant_local_class_name_highlighting=hint
-resharper_redundant_local_function_name_highlighting=hint
-resharper_redundant_logical_conditional_expression_operand_highlighting=warning
-resharper_redundant_me_qualifier_highlighting=warning
-resharper_redundant_my_base_qualifier_highlighting=warning
-resharper_redundant_my_class_qualifier_highlighting=warning
-resharper_redundant_name_qualifier_highlighting=warning
-resharper_redundant_not_null_constraint_highlighting=warning
-resharper_redundant_nullable_annotation_on_reference_type_constraint_highlighting=warning
-resharper_redundant_nullable_annotation_on_type_constraint_has_non_nullable_base_type_highlighting=warning
-resharper_redundant_nullable_annotation_on_type_constraint_has_non_nullable_type_kind_highlighting=warning
-resharper_redundant_nullable_flow_attribute_highlighting=warning
-resharper_redundant_nullable_type_mark_highlighting=warning
-resharper_redundant_nullness_attribute_with_nullable_reference_types_highlighting=warning
-resharper_redundant_overflow_checking_context_highlighting=warning
-resharper_redundant_overload_global_highlighting=suggestion
-resharper_redundant_overload_local_highlighting=suggestion
-resharper_redundant_overridden_member_highlighting=warning
-resharper_redundant_params_highlighting=warning
-resharper_redundant_parentheses_highlighting=none
-resharper_redundant_parent_type_declaration_highlighting=warning
-resharper_redundant_pattern_parentheses_highlighting=hint
-resharper_redundant_property_parentheses_highlighting=hint
-resharper_redundant_property_pattern_clause_highlighting=suggestion
-resharper_redundant_qualifier_highlighting=warning
-resharper_redundant_query_order_by_ascending_keyword_highlighting=hint
-resharper_redundant_range_bound_highlighting=suggestion
-resharper_redundant_readonly_modifier_highlighting=suggestion
-resharper_redundant_record_body_highlighting=warning
-resharper_redundant_record_class_keyword_highlighting=warning
-resharper_redundant_setter_value_parameter_declaration_highlighting=hint
-resharper_redundant_space_highlighting=none
-resharper_redundant_string_format_call_highlighting=warning
-resharper_redundant_string_interpolation_highlighting=suggestion
-resharper_redundant_string_to_char_array_call_highlighting=warning
-resharper_redundant_string_type_highlighting=suggestion
-resharper_redundant_suppress_nullable_warning_expression_highlighting=warning
-resharper_redundant_ternary_expression_highlighting=warning
-resharper_redundant_to_string_call_for_value_type_highlighting=hint
-resharper_redundant_to_string_call_highlighting=warning
-resharper_redundant_type_arguments_of_method_highlighting=warning
-resharper_redundant_type_cast_highlighting=warning
-resharper_redundant_type_cast_structural_highlighting=warning
-resharper_redundant_type_check_in_pattern_highlighting=warning
-resharper_redundant_units_highlighting=warning
-resharper_redundant_unsafe_context_highlighting=warning
-resharper_redundant_using_directive_global_highlighting=warning
-resharper_redundant_using_directive_highlighting=warning
-resharper_redundant_variable_type_specification_highlighting=hint
-resharper_redundant_verbatim_prefix_highlighting=suggestion
-resharper_redundant_verbatim_string_prefix_highlighting=suggestion
-resharper_redundant_with_expression_highlighting=suggestion
-resharper_reference_equals_with_value_type_highlighting=warning
-resharper_reg_exp_inspections_highlighting=warning
-resharper_remove_constructor_invocation_highlighting=none
-resharper_remove_redundant_braces_highlighting=none
-resharper_remove_redundant_or_statement_false_highlighting=suggestion
-resharper_remove_redundant_or_statement_true_highlighting=suggestion
-resharper_remove_to_list_1_highlighting=suggestion
-resharper_remove_to_list_2_highlighting=suggestion
-resharper_replace_auto_property_with_computed_property_highlighting=hint
-resharper_replace_indicing_with_array_destructuring_highlighting=hint
-resharper_replace_indicing_with_short_hand_properties_after_destructuring_highlighting=hint
-resharper_replace_object_pattern_with_var_pattern_highlighting=suggestion
-resharper_replace_slice_with_range_indexer_highlighting=hint
-resharper_replace_substring_with_range_indexer_highlighting=hint
-resharper_replace_undefined_checking_series_with_object_destructuring_highlighting=hint
-resharper_replace_with_destructuring_swap_highlighting=hint
-resharper_replace_with_first_or_default_1_highlighting=suggestion
-resharper_replace_with_first_or_default_2_highlighting=suggestion
-resharper_replace_with_first_or_default_3_highlighting=suggestion
-resharper_replace_with_first_or_default_4_highlighting=suggestion
-resharper_replace_with_last_or_default_1_highlighting=suggestion
-resharper_replace_with_last_or_default_2_highlighting=suggestion
-resharper_replace_with_last_or_default_3_highlighting=suggestion
-resharper_replace_with_last_or_default_4_highlighting=suggestion
-resharper_replace_with_of_type_1_highlighting=suggestion
-resharper_replace_with_of_type_2_highlighting=suggestion
-resharper_replace_with_of_type_3_highlighting=suggestion
-resharper_replace_with_of_type_any_1_highlighting=suggestion
-resharper_replace_with_of_type_any_2_highlighting=suggestion
-resharper_replace_with_of_type_count_1_highlighting=suggestion
-resharper_replace_with_of_type_count_2_highlighting=suggestion
-resharper_replace_with_of_type_first_1_highlighting=suggestion
-resharper_replace_with_of_type_first_2_highlighting=suggestion
-resharper_replace_with_of_type_first_or_default_1_highlighting=suggestion
-resharper_replace_with_of_type_first_or_default_2_highlighting=suggestion
-resharper_replace_with_of_type_last_1_highlighting=suggestion
-resharper_replace_with_of_type_last_2_highlighting=suggestion
-resharper_replace_with_of_type_last_or_default_1_highlighting=suggestion
-resharper_replace_with_of_type_last_or_default_2_highlighting=suggestion
-resharper_replace_with_of_type_long_count_highlighting=suggestion
-resharper_replace_with_of_type_single_1_highlighting=suggestion
-resharper_replace_with_of_type_single_2_highlighting=suggestion
-resharper_replace_with_of_type_single_or_default_1_highlighting=suggestion
-resharper_replace_with_of_type_single_or_default_2_highlighting=suggestion
-resharper_replace_with_of_type_where_highlighting=suggestion
-resharper_replace_with_simple_assignment_false_highlighting=suggestion
-resharper_replace_with_simple_assignment_true_highlighting=suggestion
-resharper_replace_with_single_assignment_false_highlighting=suggestion
-resharper_replace_with_single_assignment_true_highlighting=suggestion
-resharper_replace_with_single_call_to_any_highlighting=suggestion
-resharper_replace_with_single_call_to_count_highlighting=suggestion
-resharper_replace_with_single_call_to_first_highlighting=suggestion
-resharper_replace_with_single_call_to_first_or_default_highlighting=suggestion
-resharper_replace_with_single_call_to_last_highlighting=suggestion
-resharper_replace_with_single_call_to_last_or_default_highlighting=suggestion
-resharper_replace_with_single_call_to_single_highlighting=suggestion
-resharper_replace_with_single_call_to_single_or_default_highlighting=suggestion
-resharper_replace_with_single_or_default_1_highlighting=suggestion
-resharper_replace_with_single_or_default_2_highlighting=suggestion
-resharper_replace_with_single_or_default_3_highlighting=suggestion
-resharper_replace_with_single_or_default_4_highlighting=suggestion
-resharper_replace_with_string_is_null_or_empty_highlighting=suggestion
-resharper_required_base_types_conflict_highlighting=warning
-resharper_required_base_types_direct_conflict_highlighting=warning
-resharper_required_base_types_is_not_inherited_highlighting=warning
-resharper_requires_fallback_color_highlighting=warning
-resharper_resource_item_not_resolved_highlighting=error
-resharper_resource_not_resolved_highlighting=error
-resharper_resx_not_resolved_highlighting=warning
-resharper_return_from_global_scopet_with_value_highlighting=warning
-resharper_return_type_can_be_enumerable_global_highlighting=hint
-resharper_return_type_can_be_enumerable_local_highlighting=hint
-resharper_return_type_can_be_not_nullable_highlighting=warning
-resharper_return_value_of_pure_method_is_not_used_highlighting=warning
-resharper_route_templates_action_route_prefix_can_be_extracted_to_controller_route_highlighting=hint
-resharper_route_templates_ambiguous_matching_constraint_constructor_highlighting=warning
-resharper_route_templates_ambiguous_route_match_highlighting=warning
-resharper_route_templates_constraint_argument_cannot_be_converted_highlighting=warning
-resharper_route_templates_controller_route_parameter_is_not_passed_to_methods_highlighting=hint
-resharper_route_templates_duplicated_parameter_highlighting=warning
-resharper_route_templates_matching_constraint_constructor_not_resolved_highlighting=warning
-resharper_route_templates_method_missing_route_parameters_highlighting=hint
-resharper_route_templates_optional_parameter_can_be_preceded_only_by_single_period_highlighting=warning
-resharper_route_templates_optional_parameter_must_be_at_the_end_of_segment_highlighting=warning
-resharper_route_templates_parameter_constraint_can_be_specified_highlighting=hint
-resharper_route_templates_parameter_type_and_constraints_mismatch_highlighting=warning
-resharper_route_templates_parameter_type_can_be_made_stricter_highlighting=suggestion
-resharper_route_templates_route_parameter_constraint_not_resolved_highlighting=warning
-resharper_route_templates_route_parameter_is_not_passed_to_method_highlighting=hint
-resharper_route_templates_route_token_not_resolved_highlighting=warning
-resharper_route_templates_symbol_not_resolved_highlighting=warning
-resharper_route_templates_syntax_error_highlighting=warning
-resharper_safe_cast_is_used_as_type_check_highlighting=suggestion
-resharper_same_imports_with_different_name_highlighting=warning
-resharper_same_variable_assignment_highlighting=warning
-resharper_script_tag_has_both_src_and_content_attributes_highlighting=error
-resharper_script_tag_with_content_before_includes_highlighting=hint
-resharper_sealed_member_in_sealed_class_highlighting=warning
-resharper_separate_control_transfer_statement_highlighting=none
-resharper_service_contract_without_operations_highlighting=warning
-resharper_shift_expression_real_shift_count_is_zero_highlighting=warning
-resharper_shift_expression_result_equals_zero_highlighting=warning
-resharper_shift_expression_right_operand_not_equal_real_count_highlighting=warning
-resharper_shift_expression_zero_left_operand_highlighting=warning
-resharper_similar_anonymous_type_nearby_highlighting=hint
-resharper_similar_expressions_comparison_highlighting=warning
-resharper_simplify_conditional_operator_highlighting=suggestion
-resharper_simplify_conditional_ternary_expression_highlighting=suggestion
-resharper_simplify_i_if_highlighting=suggestion
-resharper_simplify_linq_expression_use_all_highlighting=suggestion
-resharper_simplify_linq_expression_use_any_highlighting=suggestion
-resharper_simplify_string_interpolation_highlighting=suggestion
-resharper_specify_a_culture_in_string_conversion_explicitly_highlighting=warning
-resharper_specify_string_comparison_highlighting=hint
-resharper_specify_variable_type_explicitly_highlighting=hint
-resharper_spin_lock_in_readonly_field_highlighting=warning
-resharper_stack_alloc_inside_loop_highlighting=warning
-resharper_statement_termination_highlighting=warning
-resharper_static_member_initializer_referes_to_member_below_highlighting=warning
-resharper_static_member_in_generic_type_highlighting=none
-resharper_static_problem_in_text_highlighting=warning
-resharper_string_compare_is_culture_specific_1_highlighting=warning
-resharper_string_compare_is_culture_specific_2_highlighting=warning
-resharper_string_compare_is_culture_specific_3_highlighting=warning
-resharper_string_compare_is_culture_specific_4_highlighting=warning
-resharper_string_compare_is_culture_specific_5_highlighting=warning
-resharper_string_compare_is_culture_specific_6_highlighting=warning
-resharper_string_compare_to_is_culture_specific_highlighting=warning
-resharper_string_concatenation_to_template_string_highlighting=hint
-resharper_string_ends_with_is_culture_specific_highlighting=none
-resharper_string_index_of_is_culture_specific_1_highlighting=warning
-resharper_string_index_of_is_culture_specific_2_highlighting=warning
-resharper_string_index_of_is_culture_specific_3_highlighting=warning
-resharper_string_last_index_of_is_culture_specific_1_highlighting=warning
-resharper_string_last_index_of_is_culture_specific_2_highlighting=warning
-resharper_string_last_index_of_is_culture_specific_3_highlighting=warning
-resharper_string_literal_as_interpolation_argument_highlighting=suggestion
-resharper_string_literal_typo_highlighting=suggestion
-resharper_string_literal_wrong_quotes_highlighting=hint
-resharper_string_starts_with_is_culture_specific_highlighting=none
-resharper_structured_message_template_problem_highlighting=warning
-resharper_struct_can_be_made_read_only_highlighting=suggestion
-resharper_struct_member_can_be_made_read_only_highlighting=none
-resharper_suggest_base_type_for_parameter_highlighting=hint
-resharper_suggest_base_type_for_parameter_in_constructor_highlighting=hint
-resharper_suggest_discard_declaration_var_style_highlighting=hint
resharper_suggest_var_or_type_built_in_types_highlighting=hint
-resharper_suggest_var_or_type_deconstruction_declarations_highlighting=hint
resharper_suggest_var_or_type_elsewhere_highlighting=hint
resharper_suggest_var_or_type_simple_types_highlighting=hint
-resharper_super_call_highlighting=suggestion
-resharper_super_call_prohibits_this_highlighting=error
-resharper_suppress_nullable_warning_expression_as_inverted_is_expression_highlighting=warning
-resharper_suspicious_instanceof_check_highlighting=warning
-resharper_suspicious_lambda_block_highlighting=warning
-resharper_suspicious_lock_over_synchronization_primitive_highlighting=warning
-resharper_suspicious_math_sign_method_highlighting=warning
-resharper_suspicious_parameter_name_in_argument_null_exception_highlighting=warning
-resharper_suspicious_this_usage_highlighting=warning
-resharper_suspicious_typeof_check_highlighting=warning
-resharper_suspicious_type_conversion_global_highlighting=warning
-resharper_swap_via_deconstruction_highlighting=suggestion
-resharper_switch_expression_handles_some_known_enum_values_with_exception_in_default_highlighting=hint
-resharper_switch_statement_for_enum_misses_default_section_highlighting=hint
-resharper_switch_statement_handles_some_known_enum_values_with_default_highlighting=hint
-resharper_switch_statement_missing_some_enum_cases_no_default_highlighting=none
-resharper_symbol_from_not_copied_locally_reference_used_warning_highlighting=warning
-resharper_syntax_is_not_allowed_highlighting=warning
-resharper_tabs_and_spaces_mismatch_highlighting=none
-resharper_tabs_are_disallowed_highlighting=none
-resharper_tabs_outside_indent_highlighting=none
-resharper_tail_recursive_call_highlighting=hint
-resharper_tasks_not_loaded_highlighting=warning
-resharper_ternary_can_be_replaced_by_its_condition_highlighting=warning
-resharper_this_in_global_context_highlighting=warning
-resharper_thread_static_at_instance_field_highlighting=warning
-resharper_thread_static_field_has_initializer_highlighting=warning
-resharper_throw_must_be_followed_by_expression_highlighting=error
-resharper_too_wide_local_variable_scope_highlighting=suggestion
-resharper_try_cast_always_succeeds_highlighting=suggestion
-resharper_try_statements_can_be_merged_highlighting=hint
-resharper_ts_not_resolved_highlighting=error
-resharper_ts_resolved_from_inaccessible_module_highlighting=error
-resharper_type_guard_doesnt_affect_anything_highlighting=warning
-resharper_type_guard_produces_never_type_highlighting=warning
-resharper_type_parameter_can_be_variant_highlighting=suggestion
-resharper_type_parameter_hides_type_param_from_outer_scope_highlighting=warning
-resharper_ul_tag_contains_non_li_elements_highlighting=hint
-resharper_unassigned_field_global_highlighting=suggestion
-resharper_unassigned_field_local_highlighting=warning
-resharper_unassigned_get_only_auto_property_highlighting=warning
-resharper_unassigned_readonly_field_highlighting=warning
-resharper_unclosed_script_highlighting=error
-resharper_undeclared_global_variable_using_highlighting=warning
-resharper_unexpected_value_highlighting=error
-resharper_unknown_css_class_highlighting=warning
-resharper_unknown_css_variable_highlighting=warning
-resharper_unknown_css_vendor_extension_highlighting=hint
-resharper_unknown_item_group_highlighting=warning
-resharper_unknown_metadata_highlighting=warning
-resharper_unknown_output_parameter_highlighting=warning
-resharper_unknown_property_highlighting=warning
-resharper_unknown_target_highlighting=warning
-resharper_unknown_task_attribute_highlighting=warning
-resharper_unknown_task_highlighting=warning
-resharper_unnecessary_whitespace_highlighting=none
-resharper_unreachable_switch_arm_due_to_integer_analysis_highlighting=warning
-resharper_unreachable_switch_case_due_to_integer_analysis_highlighting=warning
-resharper_unreal_header_tool_error_highlighting=error
-resharper_unreal_header_tool_parser_error_highlighting=error
-resharper_unreal_header_tool_warning_highlighting=warning
-resharper_unsafe_comma_in_object_properties_list_highlighting=warning
-resharper_unsupported_required_base_type_highlighting=warning
-resharper_unused_anonymous_method_signature_highlighting=warning
-resharper_unused_auto_property_accessor_global_highlighting=warning
-resharper_unused_auto_property_accessor_local_highlighting=warning
-resharper_unused_import_clause_highlighting=warning
-resharper_unused_inherited_parameter_highlighting=hint
-resharper_unused_locals_highlighting=warning
-resharper_unused_local_function_highlighting=warning
-resharper_unused_local_function_parameter_highlighting=warning
-resharper_unused_local_function_return_value_highlighting=warning
-resharper_unused_local_import_highlighting=warning
-resharper_unused_member_global_highlighting=suggestion
-resharper_unused_member_hierarchy_global_highlighting=suggestion
-resharper_unused_member_hierarchy_local_highlighting=warning
-resharper_unused_member_in_super_global_highlighting=suggestion
-resharper_unused_member_in_super_local_highlighting=warning
-resharper_unused_member_local_highlighting=warning
-resharper_unused_method_return_value_global_highlighting=suggestion
-resharper_unused_method_return_value_local_highlighting=warning
-resharper_unused_parameter_global_highlighting=suggestion
-resharper_unused_parameter_highlighting=warning
-resharper_unused_parameter_in_partial_method_highlighting=warning
-resharper_unused_parameter_local_highlighting=warning
-resharper_unused_property_highlighting=warning
-resharper_unused_tuple_component_in_return_value_highlighting=warning
-resharper_unused_type_global_highlighting=suggestion
-resharper_unused_type_local_highlighting=warning
-resharper_unused_type_parameter_highlighting=warning
-resharper_unused_variable_highlighting=warning
-resharper_usage_of_definitely_unassigned_value_highlighting=warning
-resharper_usage_of_possibly_unassigned_value_highlighting=warning
-resharper_useless_binary_operation_highlighting=warning
-resharper_useless_comparison_to_integral_constant_highlighting=warning
-resharper_use_array_creation_expression_1_highlighting=suggestion
-resharper_use_array_creation_expression_2_highlighting=suggestion
-resharper_use_array_empty_method_highlighting=suggestion
-resharper_use_as_instead_of_type_cast_highlighting=hint
-resharper_use_await_using_highlighting=suggestion
-resharper_use_cancellation_token_for_i_async_enumerable_highlighting=suggestion
-resharper_use_collection_count_property_highlighting=suggestion
-resharper_use_configure_await_false_for_async_disposable_highlighting=none
-resharper_use_configure_await_false_highlighting=suggestion
-resharper_use_deconstruction_highlighting=hint
-resharper_use_deconstruction_on_parameter_highlighting=hint
-resharper_use_empty_types_field_highlighting=suggestion
-resharper_use_event_args_empty_field_highlighting=suggestion
-resharper_use_format_specifier_in_format_string_highlighting=suggestion
-resharper_use_implicitly_typed_variable_evident_highlighting=hint
-resharper_use_implicitly_typed_variable_highlighting=none
-resharper_use_implicit_by_val_modifier_highlighting=hint
-resharper_use_indexed_property_highlighting=suggestion
-resharper_use_index_from_end_expression_highlighting=suggestion
-resharper_use_is_operator_1_highlighting=suggestion
-resharper_use_is_operator_2_highlighting=suggestion
-resharper_use_method_any_0_highlighting=suggestion
-resharper_use_method_any_1_highlighting=suggestion
-resharper_use_method_any_2_highlighting=suggestion
-resharper_use_method_any_3_highlighting=suggestion
-resharper_use_method_any_4_highlighting=suggestion
-resharper_use_method_is_instance_of_type_highlighting=suggestion
-resharper_use_nameof_expression_for_part_of_the_string_highlighting=none
-resharper_use_nameof_expression_highlighting=suggestion
-resharper_use_name_of_instead_of_type_of_highlighting=suggestion
-resharper_use_negated_pattern_in_is_expression_highlighting=hint
-resharper_use_negated_pattern_matching_highlighting=hint
-resharper_use_nullable_annotation_instead_of_attribute_highlighting=suggestion
-resharper_use_nullable_attributes_supported_by_compiler_highlighting=suggestion
-resharper_use_nullable_reference_types_annotation_syntax_highlighting=warning
-resharper_use_null_propagation_highlighting=hint
-resharper_use_null_propagation_when_possible_highlighting=none
-resharper_use_object_or_collection_initializer_highlighting=suggestion
-resharper_use_of_implicit_global_in_function_scope_highlighting=warning
-resharper_use_of_possibly_unassigned_property_highlighting=warning
-resharper_use_pattern_matching_highlighting=suggestion
-resharper_use_positional_deconstruction_pattern_highlighting=none
-resharper_use_string_interpolation_highlighting=suggestion
-resharper_use_switch_case_pattern_variable_highlighting=suggestion
-resharper_use_throw_if_null_method_highlighting=none
-resharper_use_verbatim_string_highlighting=hint
-resharper_using_of_reserved_word_error_highlighting=error
-resharper_using_of_reserved_word_highlighting=warning
-resharper_value_parameter_not_used_highlighting=warning
-resharper_value_range_attribute_violation_highlighting=warning
-resharper_value_should_have_units_highlighting=error
-resharper_variable_can_be_made_const_highlighting=hint
-resharper_variable_can_be_made_let_highlighting=hint
-resharper_variable_can_be_moved_to_inner_block_highlighting=hint
-resharper_variable_can_be_not_nullable_highlighting=warning
-resharper_variable_hides_outer_variable_highlighting=warning
-resharper_variable_used_before_declared_highlighting=warning
-resharper_variable_used_in_inner_scope_before_declared_highlighting=warning
-resharper_variable_used_out_of_scope_highlighting=warning
-resharper_vb_check_for_reference_equality_instead_1_highlighting=suggestion
-resharper_vb_check_for_reference_equality_instead_2_highlighting=suggestion
-resharper_vb_possible_mistaken_argument_highlighting=warning
-resharper_vb_possible_mistaken_call_to_get_type_1_highlighting=warning
-resharper_vb_possible_mistaken_call_to_get_type_2_highlighting=warning
-resharper_vb_remove_to_list_1_highlighting=suggestion
-resharper_vb_remove_to_list_2_highlighting=suggestion
-resharper_vb_replace_with_first_or_default_highlighting=suggestion
-resharper_vb_replace_with_last_or_default_highlighting=suggestion
-resharper_vb_replace_with_of_type_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_any_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_any_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_count_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_count_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_first_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_first_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_first_or_default_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_first_or_default_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_last_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_last_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_last_or_default_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_last_or_default_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_single_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_single_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_single_or_default_1_highlighting=suggestion
-resharper_vb_replace_with_of_type_single_or_default_2_highlighting=suggestion
-resharper_vb_replace_with_of_type_where_highlighting=suggestion
-resharper_vb_replace_with_single_assignment_1_highlighting=suggestion
-resharper_vb_replace_with_single_assignment_2_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_any_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_count_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_first_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_first_or_default_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_last_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_last_or_default_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_single_highlighting=suggestion
-resharper_vb_replace_with_single_call_to_single_or_default_highlighting=suggestion
-resharper_vb_replace_with_single_or_default_highlighting=suggestion
-resharper_vb_simplify_linq_expression_10_highlighting=hint
-resharper_vb_simplify_linq_expression_1_highlighting=suggestion
-resharper_vb_simplify_linq_expression_2_highlighting=suggestion
-resharper_vb_simplify_linq_expression_3_highlighting=suggestion
-resharper_vb_simplify_linq_expression_4_highlighting=suggestion
-resharper_vb_simplify_linq_expression_5_highlighting=suggestion
-resharper_vb_simplify_linq_expression_6_highlighting=suggestion
-resharper_vb_simplify_linq_expression_7_highlighting=hint
-resharper_vb_simplify_linq_expression_8_highlighting=hint
-resharper_vb_simplify_linq_expression_9_highlighting=hint
-resharper_vb_string_compare_is_culture_specific_1_highlighting=warning
-resharper_vb_string_compare_is_culture_specific_2_highlighting=warning
-resharper_vb_string_compare_is_culture_specific_3_highlighting=warning
-resharper_vb_string_compare_is_culture_specific_4_highlighting=warning
-resharper_vb_string_compare_is_culture_specific_5_highlighting=warning
-resharper_vb_string_compare_is_culture_specific_6_highlighting=warning
-resharper_vb_string_compare_to_is_culture_specific_highlighting=warning
-resharper_vb_string_ends_with_is_culture_specific_highlighting=none
-resharper_vb_string_index_of_is_culture_specific_1_highlighting=warning
-resharper_vb_string_index_of_is_culture_specific_2_highlighting=warning
-resharper_vb_string_index_of_is_culture_specific_3_highlighting=warning
-resharper_vb_string_last_index_of_is_culture_specific_1_highlighting=warning
-resharper_vb_string_last_index_of_is_culture_specific_2_highlighting=warning
-resharper_vb_string_last_index_of_is_culture_specific_3_highlighting=warning
-resharper_vb_string_starts_with_is_culture_specific_highlighting=none
-resharper_vb_unreachable_code_highlighting=warning
-resharper_vb_use_array_creation_expression_1_highlighting=suggestion
-resharper_vb_use_array_creation_expression_2_highlighting=suggestion
-resharper_vb_use_first_instead_highlighting=warning
-resharper_vb_use_method_any_1_highlighting=suggestion
-resharper_vb_use_method_any_2_highlighting=suggestion
-resharper_vb_use_method_any_3_highlighting=suggestion
-resharper_vb_use_method_any_4_highlighting=suggestion
-resharper_vb_use_method_any_5_highlighting=suggestion
-resharper_vb_use_method_is_instance_of_type_highlighting=suggestion
-resharper_vb_use_type_of_is_operator_1_highlighting=suggestion
-resharper_vb_use_type_of_is_operator_2_highlighting=suggestion
-resharper_virtual_member_call_in_constructor_highlighting=warning
-resharper_virtual_member_never_overridden_global_highlighting=suggestion
-resharper_virtual_member_never_overridden_local_highlighting=suggestion
-resharper_void_method_with_must_use_return_value_attribute_highlighting=warning
-resharper_web_config_module_not_resolved_highlighting=error
-resharper_web_config_module_qualification_resolve_highlighting=warning
-resharper_web_config_redundant_add_namespace_tag_highlighting=warning
-resharper_web_config_redundant_location_tag_highlighting=warning
-resharper_web_config_tag_prefix_redundand_highlighting=warning
-resharper_web_config_type_not_resolved_highlighting=error
-resharper_web_config_unused_add_tag_highlighting=warning
-resharper_web_config_unused_element_due_to_config_source_attribute_highlighting=warning
-resharper_web_config_unused_remove_or_clear_tag_highlighting=warning
-resharper_web_config_web_config_path_warning_highlighting=warning
-resharper_web_config_wrong_module_highlighting=error
-resharper_web_ignored_path_highlighting=none
-resharper_web_mapped_path_highlighting=hint
-resharper_with_expression_instead_of_initializer_highlighting=suggestion
-resharper_with_statement_using_error_highlighting=error
-resharper_wrong_expression_statement_highlighting=warning
-resharper_wrong_indent_size_highlighting=none
-resharper_wrong_metadata_use_highlighting=none
-resharper_wrong_public_modifier_specification_highlighting=hint
-resharper_wrong_require_relative_path_highlighting=hint
-resharper_xaml_assign_null_to_not_null_attribute_highlighting=warning
-resharper_xaml_avalonia_wrong_binding_mode_for_stream_binding_operator_highlighting=warning
-resharper_xaml_binding_without_context_not_resolved_highlighting=hint
-resharper_xaml_binding_with_context_not_resolved_highlighting=warning
-resharper_xaml_compiled_binding_missing_data_type_error_highlighting_highlighting=error
-resharper_xaml_constructor_warning_highlighting=warning
-resharper_xaml_decimal_parsing_is_culture_dependent_highlighting=warning
-resharper_xaml_dependency_property_resolve_error_highlighting=warning
-resharper_xaml_duplicate_style_setter_highlighting=warning
-resharper_xaml_dynamic_resource_error_highlighting=error
-resharper_xaml_element_name_reference_not_resolved_highlighting=error
-resharper_xaml_empty_grid_length_definition_highlighting=error
-resharper_xaml_grid_definitions_can_be_converted_to_attribute_highlighting=hint
-resharper_xaml_ignored_path_highlighting_highlighting=none
-resharper_xaml_index_out_of_grid_definition_highlighting=warning
-resharper_xaml_invalid_member_type_highlighting=error
-resharper_xaml_invalid_resource_target_type_highlighting=error
-resharper_xaml_invalid_resource_type_highlighting=error
-resharper_xaml_invalid_type_highlighting=error
-resharper_xaml_language_level_highlighting=error
-resharper_xaml_mapped_path_highlighting_highlighting=hint
-resharper_xaml_method_arguments_will_be_ignored_highlighting=warning
-resharper_xaml_missing_grid_index_highlighting=warning
-resharper_xaml_overloads_collision_highlighting=warning
-resharper_xaml_parent_is_out_of_current_component_tree_highlighting=warning
-resharper_xaml_path_error_highlighting=warning
-resharper_xaml_possible_null_reference_exception_highlighting=suggestion
-resharper_xaml_redundant_attached_property_highlighting=warning
-resharper_xaml_redundant_binding_mode_attribute_highlighting=warning
-resharper_xaml_redundant_collection_property_highlighting=warning
-resharper_xaml_redundant_freeze_attribute_highlighting=warning
-resharper_xaml_redundant_grid_definitions_highlighting=warning
-resharper_xaml_redundant_grid_span_highlighting=warning
-resharper_xaml_redundant_modifiers_attribute_highlighting=warning
-resharper_xaml_redundant_namespace_alias_highlighting=warning
-resharper_xaml_redundant_name_attribute_highlighting=warning
-resharper_xaml_redundant_property_type_qualifier_highlighting=warning
-resharper_xaml_redundant_resource_highlighting=warning
-resharper_xaml_redundant_styled_value_highlighting=warning
-resharper_xaml_redundant_update_source_trigger_attribute_highlighting=warning
-resharper_xaml_redundant_xamarin_forms_class_declaration_highlighting=warning
-resharper_xaml_resource_file_path_case_mismatch_highlighting=warning
-resharper_xaml_routed_event_resolve_error_highlighting=warning
-resharper_xaml_static_resource_not_resolved_highlighting=warning
-resharper_xaml_style_class_not_found_highlighting=warning
-resharper_xaml_style_invalid_target_type_highlighting=error
-resharper_xaml_unexpected_text_token_highlighting=error
-resharper_xaml_xaml_duplicate_device_family_type_view_highlighting_highlighting=error
-resharper_xaml_xaml_mismatched_device_family_view_clr_name_highlighting_highlighting=warning
-resharper_xaml_xaml_relative_source_default_mode_warning_highlighting_highlighting=warning
-resharper_xaml_xaml_unknown_device_family_type_highlighting_highlighting=warning
-resharper_xaml_xaml_xamarin_forms_data_type_and_binding_context_type_mismatched_highlighting_highlighting=warning
-resharper_xaml_x_key_attribute_disallowed_highlighting=error
-resharper_xml_doc_comment_syntax_problem_highlighting=warning
-resharper_xunit_xunit_test_with_console_output_highlighting=warning
-csharp_style_prefer_implicitly_typed_lambda_expression = true:suggestion
-csharp_style_expression_bodied_methods = true:silent
-csharp_style_prefer_tuple_swap = true:suggestion
-csharp_style_prefer_unbound_generic_type_in_nameof = true:suggestion
-csharp_style_prefer_utf8_string_literals = true:suggestion
-csharp_style_inlined_variable_declaration = true:suggestion
-csharp_style_expression_bodied_constructors = true:silent
-csharp_style_expression_bodied_operators = true:silent
-csharp_style_deconstructed_variable_declaration = true:suggestion
-csharp_style_unused_value_assignment_preference = discard_variable:suggestion
-csharp_style_unused_value_expression_statement_preference = discard_variable:silent
-csharp_style_expression_bodied_properties = true:silent
+resharper_web_config_module_not_resolved_highlighting=warning
+resharper_web_config_type_not_resolved_highlighting=warning
+resharper_web_config_wrong_module_highlighting=warning
-[*.{cshtml,htm,html,proto,razor}]
-indent_style=tab
-indent_size=tab
-tab_width=4
-
-[*.{asax,ascx,aspx,axaml,c,c++,cc,cginc,compute,cp,cpp,cs,css,cu,cuh,cxx,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,js,jsx,master,mpp,mq4,mq5,mqh,paml,skin,tpp,ts,tsx,usf,ush,vb,xaml,xamlx,xoml}]
+[*.{appxmanifest,asax,ascx,aspx,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style=space
indent_size=4
tab_width=4
-
-[ "*.proto" ]
-indent_style=tab
-indent_size=tab
-tab_width=4
-
-[*.{asax,ascx,aspx,axaml,cs,cshtml,css,htm,html,js,jsx,master,paml,razor,skin,ts,tsx,vb,xaml,xamlx,xoml}]
-indent_style=space
-indent_size=4
-tab_width=4
-
-[*.{appxmanifest,axml,build,config,csproj,dbml,discomap,dtd,json,jsproj,lsproj,njsproj,nuspec,proj,props,resjson,resw,resx,StyleCop,targets,tasks,vbproj,xml,xsd}]
-indent_style=space
-indent_size=2
-tab_width=2
-
-[*.{appxmanifest,asax,ascx,aspx,axaml,axml,build,c,c++,cc,cginc,compute,config,cp,cpp,cs,cshtml,csproj,css,cu,cuh,cxx,dbml,discomap,dtd,h,hh,hlsl,hlsli,hlslinc,hpp,htm,html,hxx,inc,inl,ino,ipp,js,json,jsproj,jsx,lsproj,master,mpp,mq4,mq5,mqh,njsproj,nuspec,paml,proj,props,proto,razor,resjson,resw,resx,skin,StyleCop,targets,tasks,tpp,ts,tsx,usf,ush,vb,vbproj,xaml,xamlx,xml,xoml,xsd}]
-indent_style=space
-indent_size= 4
-tab_width= 4
-dotnet_style_operator_placement_when_wrapping = beginning_of_line
-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:silent
-dotnet_style_object_initializer = true:suggestion
-dotnet_style_collection_initializer = true:suggestion
-dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
-dotnet_style_prefer_conditional_expression_over_assignment = true:silent
-dotnet_style_prefer_conditional_expression_over_return = true: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
-insert_final_newline = true
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1a61439e..54e31343 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,15 +10,11 @@ jobs:
build:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v5
- with:
- submodules: recursive
+ - uses: actions/checkout@v2
- name: Setup .NET
- uses: actions/setup-dotnet@v5
+ uses: actions/setup-dotnet@v1
with:
- dotnet-version: |
- 10.x.x
- 9.x.x
+ dotnet-version: 5.0.100
- name: Restore dependencies
run: dotnet restore
- name: Download Dalamud
@@ -29,9 +25,9 @@ jobs:
run: |
dotnet build --no-restore --configuration Release --nologo
- name: Archive
- run: Compress-Archive -Path Penumbra/bin/Release/* -DestinationPath Penumbra.zip
+ run: Compress-Archive -Path Penumbra/bin/Release/net5.0-windows/* -DestinationPath Penumbra.zip
- name: Upload a Build Artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v2.2.1
with:
path: |
- ./Penumbra/bin/Release/*
+ ./Penumbra/bin/Release/net5.0-windows/*
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c72b4800..763348f6 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -2,22 +2,18 @@ name: Create Release
on:
push:
- tags-ignore:
- - testing_*
+ tags:
+ - '*'
jobs:
build:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v5
- with:
- submodules: recursive
+ - uses: actions/checkout@v2
- name: Setup .NET
- uses: actions/setup-dotnet@v5
+ uses: actions/setup-dotnet@v1
with:
- dotnet-version: |
- 10.x.x
- 9.x.x
+ dotnet-version: 5.0.100
- name: Restore dependencies
run: dotnet restore
- name: Download Dalamud
@@ -26,23 +22,22 @@ jobs:
Expand-Archive -Force latest.zip "$env:AppData\XIVLauncher\addon\Hooks\dev"
- name: Build
run: |
- $ver = '${{ github.ref_name }}'
- invoke-expression 'dotnet build --no-restore --configuration Release --nologo -p:Version=$ver -p:FileVersion=$ver -p:AssemblyVersion=$ver'
- - name: write version into jsons
+ $ver = '${{ github.ref }}' -replace 'refs/tags/',''
+ invoke-expression 'dotnet build --no-restore --configuration Release --nologo -p:Version=$ver -p:FileVersion=$ver'
+ - name: write version into json
run: |
- $ver = '${{ github.ref_name }}'
- $path = './Penumbra/bin/Release/Penumbra.json'
- $json = Get-Content -Raw $path | ConvertFrom-Json
- $json.AssemblyVersion = $ver
- $content = $json | ConvertTo-Json
+ $ver = '${{ github.ref }}' -replace 'refs/tags/',''
+ $path = './Penumbra/bin/Release/net5.0-windows/Penumbra.json'
+ $content = get-content -path $path
+ $content = $content -replace '1.0.0.0',$ver
set-content -Path $path -Value $content
- name: Archive
- run: Compress-Archive -Path Penumbra/bin/Release/* -DestinationPath Penumbra.zip
+ run: Compress-Archive -Path Penumbra/bin/Release/net5.0-windows/* -DestinationPath Penumbra.zip
- name: Upload a Build Artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v2.2.1
with:
path: |
- ./Penumbra/bin/Release/*
+ ./Penumbra/bin/Release/net5.0-windows/*
- name: Create Release
id: create_release
uses: actions/create-release@v1
@@ -66,24 +61,20 @@ jobs:
- name: Write out repo.json
run: |
- $ver = '${{ github.ref_name }}'
- $path = './repo.json'
- $json = Get-Content -Raw $path | ConvertFrom-Json
- $json[0].AssemblyVersion = $ver
- $json[0].TestingAssemblyVersion = $ver
- $json[0].DownloadLinkInstall = $json.DownloadLinkInstall -replace '[^/]+/Penumbra.zip',"$ver/Penumbra.zip"
- $json[0].DownloadLinkTesting = $json.DownloadLinkTesting -replace '[^/]+/Penumbra.zip',"$ver/Penumbra.zip"
- $json[0].DownloadLinkUpdate = $json.DownloadLinkUpdate -replace '[^/]+/Penumbra.zip',"$ver/Penumbra.zip"
- $content = $json | ConvertTo-Json -AsArray
- set-content -Path $path -Value $content
+ $ver = '${{ github.ref }}' -replace 'refs/tags/',''
+ $path = './base_repo.json'
+ $new_path = './repo.json'
+ $content = get-content -path $path
+ $content = $content -replace '1.0.0.0',$ver
+ set-content -Path $new_path -Value $content
- name: Commit repo.json
run: |
git config --global user.name "Actions User"
git config --global user.email "actions@github.com"
- git fetch origin master
- git branch -f master ${{ github.sha }}
- git checkout master
+
+ git fetch origin master && git checkout master
git add repo.json
- git commit -m "[CI] Updating repo.json for ${{ github.ref_name }}" || true
- git push origin master
+ git commit -m "[CI] Updating repo.json for ${{ github.ref }}" || true
+
+ git push origin master || true
\ No newline at end of file
diff --git a/.github/workflows/test_release.yml b/.github/workflows/test_release.yml
deleted file mode 100644
index c6b4e459..00000000
--- a/.github/workflows/test_release.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-name: Create Test Release
-
-on:
- push:
- tags:
- - testing_*
-
-jobs:
- build:
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v5
- with:
- submodules: recursive
- - name: Setup .NET
- uses: actions/setup-dotnet@v5
- with:
- dotnet-version: |
- 10.x.x
- 9.x.x
- - name: Restore dependencies
- run: dotnet restore
- - name: Download Dalamud
- run: |
- Invoke-WebRequest -Uri https://goatcorp.github.io/dalamud-distrib/stg/latest.zip -OutFile latest.zip
- Expand-Archive -Force latest.zip "$env:AppData\XIVLauncher\addon\Hooks\dev"
- - name: Build
- run: |
- $ver = '${{ github.ref_name }}' -replace 'testing_'
- invoke-expression 'dotnet build --no-restore --configuration Debug --nologo -p:Version=$ver -p:FileVersion=$ver -p:AssemblyVersion=$ver'
- - name: write version into json
- run: |
- $ver = '${{ github.ref_name }}' -replace 'testing_'
- $path = './Penumbra/bin/Debug/Penumbra.json'
- $json = Get-Content -Raw $path | ConvertFrom-Json
- $json.AssemblyVersion = $ver
- $content = $json | ConvertTo-Json
- set-content -Path $path -Value $content
- - name: Archive
- run: Compress-Archive -Path Penumbra/bin/Debug/* -DestinationPath Penumbra.zip
- - name: Upload a Build Artifact
- uses: actions/upload-artifact@v4
- with:
- path: |
- ./Penumbra/bin/Debug/*
- - name: Create Release
- id: create_release
- uses: actions/create-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- release_name: Penumbra ${{ github.ref }}
- draft: false
- prerelease: false
- - name: Upload Release Asset
- id: upload-release-asset
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
- asset_path: ./Penumbra.zip
- asset_name: Penumbra.zip
- asset_content_type: application/zip
-
- - name: Write out repo.json
- run: |
- $verT = '${{ github.ref_name }}'
- $ver = $verT -replace 'testing_'
- $path = './repo.json'
- $json = Get-Content -Raw $path | ConvertFrom-Json
- $json[0].TestingAssemblyVersion = $ver
- $json[0].DownloadLinkTesting = $json.DownloadLinkTesting -replace '[^/]+/Penumbra.zip',"$verT/Penumbra.zip"
- $content = $json | ConvertTo-Json -AsArray
- set-content -Path $path -Value $content
-
- - name: Commit repo.json
- run: |
- git config --global user.name "Actions User"
- git config --global user.email "actions@github.com"
- git fetch origin master
- git branch -f master ${{ github.sha }}
- git checkout master
- git add repo.json
- git commit -m "[CI] Updating repo.json for ${{ github.ref_name }}" || true
- git push origin master
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index ea1199ad..00000000
--- a/.gitmodules
+++ /dev/null
@@ -1,16 +0,0 @@
-[submodule "OtterGui"]
- path = OtterGui
- url = https://github.com/Ottermandias/OtterGui.git
- branch = main
-[submodule "Penumbra.Api"]
- path = Penumbra.Api
- url = https://github.com/Ottermandias/Penumbra.Api.git
- branch = main
-[submodule "Penumbra.String"]
- path = Penumbra.String
- url = https://github.com/Ottermandias/Penumbra.String.git
- branch = main
-[submodule "Penumbra.GameData"]
- path = Penumbra.GameData
- url = https://github.com/Ottermandias/Penumbra.GameData.git
- branch = main
diff --git a/OtterGui b/OtterGui
deleted file mode 160000
index ff1e6543..00000000
--- a/OtterGui
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit ff1e6543845e3b8c53a5f8b240bc38faffb1b3bf
diff --git a/Penumbra.Api b/Penumbra.Api
deleted file mode 160000
index 52a3216a..00000000
--- a/Penumbra.Api
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 52a3216a525592205198303df2844435e382cf87
diff --git a/Penumbra.CrashHandler/Buffers/AnimationInvocationBuffer.cs b/Penumbra.CrashHandler/Buffers/AnimationInvocationBuffer.cs
deleted file mode 100644
index 292be2ff..00000000
--- a/Penumbra.CrashHandler/Buffers/AnimationInvocationBuffer.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Nodes;
-
-namespace Penumbra.CrashHandler.Buffers;
-
-/// The types of currently hooked and relevant animation loading functions.
-public enum AnimationInvocationType : int
-{
- PapLoad,
- ActionLoad,
- ScheduleClipUpdate,
- LoadTimelineResources,
- LoadCharacterVfx,
- LoadCharacterSound,
- ApricotSoundPlay,
- LoadAreaVfx,
- CharacterBaseLoadAnimation,
-}
-
-/// The full crash entry for an invoked vfx function.
-public record struct VfxFuncInvokedEntry(
- double Age,
- DateTimeOffset Timestamp,
- int ThreadId,
- string InvocationType,
- string CharacterName,
- string CharacterAddress,
- Guid CollectionId) : ICrashDataEntry;
-
-/// Only expose the write interface for the buffer.
-public interface IAnimationInvocationBufferWriter
-{
- /// Write a line into the buffer with the given data.
- /// The address of the related character, if known.
- /// The name of the related character, anonymized or relying on index if unavailable, if known.
- /// The GUID of the associated collection.
- /// The type of VFX func called.
- public void WriteLine(nint characterAddress, ReadOnlySpan characterName, Guid collectionId, AnimationInvocationType type);
-}
-
-internal sealed class AnimationInvocationBuffer : MemoryMappedBuffer, IAnimationInvocationBufferWriter, IBufferReader
-{
- private const int _version = 1;
- private const int _lineCount = 64;
- private const int _lineCapacity = 128;
- private const string _name = "Penumbra.AnimationInvocation";
-
- public void WriteLine(nint characterAddress, ReadOnlySpan characterName, Guid collectionId, AnimationInvocationType type)
- {
- var accessor = GetCurrentLineLocking();
- lock (accessor)
- {
- accessor.Write(0, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
- accessor.Write(8, Environment.CurrentManagedThreadId);
- accessor.Write(12, (int)type);
- accessor.Write(16, characterAddress);
- var span = GetSpan(accessor, 24, 16);
- collectionId.TryWriteBytes(span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- span = GetSpan(accessor, 40);
- WriteSpan(characterName, span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- }
- }
-
- public uint TotalCount
- => TotalWrittenLines;
-
- public IEnumerable GetLines(DateTimeOffset crashTime)
- {
- var lineCount = (int)CurrentLineCount;
- for (var i = lineCount - 1; i >= 0; --i)
- {
- var line = GetLine(i);
- var timestamp = DateTimeOffset.FromUnixTimeMilliseconds(BitConverter.ToInt64(line));
- var thread = BitConverter.ToInt32(line[8..]);
- var type = (AnimationInvocationType)BitConverter.ToInt32(line[12..]);
- var address = BitConverter.ToUInt64(line[16..]);
- var collectionId = new Guid(line[24..40]);
- var characterName = ReadString(line[40..]);
- yield return new JsonObject()
- {
- [nameof(VfxFuncInvokedEntry.Age)] = (crashTime - timestamp).TotalSeconds,
- [nameof(VfxFuncInvokedEntry.Timestamp)] = timestamp,
- [nameof(VfxFuncInvokedEntry.ThreadId)] = thread,
- [nameof(VfxFuncInvokedEntry.InvocationType)] = ToName(type),
- [nameof(VfxFuncInvokedEntry.CharacterName)] = characterName,
- [nameof(VfxFuncInvokedEntry.CharacterAddress)] = address.ToString("X"),
- [nameof(VfxFuncInvokedEntry.CollectionId)] = collectionId,
- };
- }
- }
-
- public static IBufferReader CreateReader(int pid)
- => new AnimationInvocationBuffer(false, pid);
-
- public static IAnimationInvocationBufferWriter CreateWriter(int pid)
- => new AnimationInvocationBuffer(pid);
-
- private AnimationInvocationBuffer(bool writer, int pid)
- : base($"{_name}_{pid}_{_version}", _version)
- { }
-
- private AnimationInvocationBuffer(int pid)
- : base($"{_name}_{pid}_{_version}", _version, _lineCount, _lineCapacity)
- { }
-
- private static string ToName(AnimationInvocationType type)
- => type switch
- {
- AnimationInvocationType.PapLoad => "PAP Load",
- AnimationInvocationType.ActionLoad => "Action Load",
- AnimationInvocationType.ScheduleClipUpdate => "Schedule Clip Update",
- AnimationInvocationType.LoadTimelineResources => "Load Timeline Resources",
- AnimationInvocationType.LoadCharacterVfx => "Load Character VFX",
- AnimationInvocationType.LoadCharacterSound => "Load Character Sound",
- AnimationInvocationType.ApricotSoundPlay => "Apricot Sound Play",
- AnimationInvocationType.LoadAreaVfx => "Load Area VFX",
- AnimationInvocationType.CharacterBaseLoadAnimation => "Load Animation (CharacterBase)",
- _ => $"Unknown ({(int)type})",
- };
-}
diff --git a/Penumbra.CrashHandler/Buffers/CharacterBaseBuffer.cs b/Penumbra.CrashHandler/Buffers/CharacterBaseBuffer.cs
deleted file mode 100644
index 89fea29d..00000000
--- a/Penumbra.CrashHandler/Buffers/CharacterBaseBuffer.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Nodes;
-
-namespace Penumbra.CrashHandler.Buffers;
-
-/// Only expose the write interface for the buffer.
-public interface ICharacterBaseBufferWriter
-{
- /// Write a line into the buffer with the given data.
- /// The address of the related character, if known.
- /// The name of the related character, anonymized or relying on index if unavailable, if known.
- /// The GUID of the associated collection.
- public void WriteLine(nint characterAddress, ReadOnlySpan characterName, Guid collectionId);
-}
-
-/// The full crash entry for a loaded character base.
-public record struct CharacterLoadedEntry(
- double Age,
- DateTimeOffset Timestamp,
- int ThreadId,
- string CharacterName,
- string CharacterAddress,
- Guid CollectionId) : ICrashDataEntry;
-
-internal sealed class CharacterBaseBuffer : MemoryMappedBuffer, ICharacterBaseBufferWriter, IBufferReader
-{
- private const int _version = 1;
- private const int _lineCount = 10;
- private const int _lineCapacity = 128;
- private const string _name = "Penumbra.CharacterBase";
-
- public void WriteLine(nint characterAddress, ReadOnlySpan characterName, Guid collectionId)
- {
- var accessor = GetCurrentLineLocking();
- lock (accessor)
- {
- accessor.Write(0, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
- accessor.Write(8, Environment.CurrentManagedThreadId);
- accessor.Write(12, characterAddress);
- var span = GetSpan(accessor, 20, 16);
- collectionId.TryWriteBytes(span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- span = GetSpan(accessor, 36);
- WriteSpan(characterName, span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- }
- }
-
- public IEnumerable GetLines(DateTimeOffset crashTime)
- {
- var lineCount = (int)CurrentLineCount;
- for (var i = lineCount - 1; i >= 0; --i)
- {
- var line = GetLine(i);
- var timestamp = DateTimeOffset.FromUnixTimeMilliseconds(BitConverter.ToInt64(line));
- var thread = BitConverter.ToInt32(line[8..]);
- var address = BitConverter.ToUInt64(line[12..]);
- var collectionId = new Guid(line[20..36]);
- var characterName = ReadString(line[36..]);
- yield return new JsonObject
- {
- [nameof(CharacterLoadedEntry.Age)] = (crashTime - timestamp).TotalSeconds,
- [nameof(CharacterLoadedEntry.Timestamp)] = timestamp,
- [nameof(CharacterLoadedEntry.ThreadId)] = thread,
- [nameof(CharacterLoadedEntry.CharacterName)] = characterName,
- [nameof(CharacterLoadedEntry.CharacterAddress)] = address.ToString("X"),
- [nameof(CharacterLoadedEntry.CollectionId)] = collectionId,
- };
- }
- }
-
- public uint TotalCount
- => TotalWrittenLines;
-
- public static IBufferReader CreateReader(int pid)
- => new CharacterBaseBuffer(false, pid);
-
- public static ICharacterBaseBufferWriter CreateWriter(int pid)
- => new CharacterBaseBuffer(pid);
-
- private CharacterBaseBuffer(bool writer, int pid)
- : base($"{_name}_{pid}_{_version}", _version)
- { }
-
- private CharacterBaseBuffer(int pid)
- : base($"{_name}_{pid}_{_version}", _version, _lineCount, _lineCapacity)
- { }
-}
diff --git a/Penumbra.CrashHandler/Buffers/MemoryMappedBuffer.cs b/Penumbra.CrashHandler/Buffers/MemoryMappedBuffer.cs
deleted file mode 100644
index e2ffcebe..00000000
--- a/Penumbra.CrashHandler/Buffers/MemoryMappedBuffer.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.IO.MemoryMappedFiles;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-
-namespace Penumbra.CrashHandler.Buffers;
-
-public class MemoryMappedBuffer : IDisposable
-{
- private const int MinHeaderLength = 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
-
- private readonly MemoryMappedFile _file;
- private readonly MemoryMappedViewAccessor _header;
- private readonly MemoryMappedViewAccessor[] _lines = [];
-
- public readonly int Version;
- public readonly uint LineCount;
- public readonly uint LineCapacity;
- private readonly uint _lineMask;
- private bool _disposed;
-
- protected uint CurrentLineCount
- {
- get => _header.ReadUInt32(16);
- set => _header.Write(16, value);
- }
-
- protected uint CurrentLinePosition
- {
- get => _header.ReadUInt32(20);
- set => _header.Write(20, value);
- }
-
- public uint TotalWrittenLines
- {
- get => _header.ReadUInt32(24);
- protected set => _header.Write(24, value);
- }
-
- public MemoryMappedBuffer(string mapName, int version, uint lineCount, uint lineCapacity)
- {
- Version = version;
- LineCount = BitOperations.RoundUpToPowerOf2(Math.Clamp(lineCount, 2, int.MaxValue >> 3));
- LineCapacity = BitOperations.RoundUpToPowerOf2(Math.Clamp(lineCapacity, 2, int.MaxValue >> 3));
- _lineMask = LineCount - 1;
- var fileName = Encoding.UTF8.GetBytes(mapName);
- var headerLength = (uint)(4 + 4 + 4 + 4 + 4 + 4 + 4 + fileName.Length + 1);
- headerLength = (headerLength & 0b111) > 0 ? (headerLength & ~0b111u) + 0b1000 : headerLength;
- var capacity = LineCount * LineCapacity + headerLength;
- _file = MemoryMappedFile.CreateNew(mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None,
- HandleInheritability.Inheritable);
- _header = _file.CreateViewAccessor(0, headerLength);
- _header.Write(0, headerLength);
- _header.Write(4, Version);
- _header.Write(8, LineCount);
- _header.Write(12, LineCapacity);
- _header.WriteArray(28, fileName, 0, fileName.Length);
- _header.Write(fileName.Length + 28, (byte)0);
- _lines = Enumerable.Range(0, (int)LineCount).Select(i
- => _file.CreateViewAccessor(headerLength + i * LineCapacity, LineCapacity, MemoryMappedFileAccess.ReadWrite))
- .ToArray();
- }
-
- public MemoryMappedBuffer(string mapName, int? expectedVersion = null, uint? expectedMinLineCount = null,
- uint? expectedMinLineCapacity = null)
- {
- _lines = [];
- _file = MemoryMappedFile.OpenExisting(mapName, MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable);
- using var headerLine = _file.CreateViewAccessor(0, 4, MemoryMappedFileAccess.Read);
- var headerLength = headerLine.ReadUInt32(0);
- if (headerLength < MinHeaderLength)
- Throw($"Map {mapName} did not contain a valid header.");
-
- _header = _file.CreateViewAccessor(0, headerLength, MemoryMappedFileAccess.ReadWrite);
- Version = _header.ReadInt32(4);
- LineCount = _header.ReadUInt32(8);
- LineCapacity = _header.ReadUInt32(12);
- _lineMask = LineCount - 1;
- if (expectedVersion.HasValue && expectedVersion.Value != Version)
- Throw($"Map {mapName} has version {Version} instead of {expectedVersion.Value}.");
-
- if (LineCount < expectedMinLineCount)
- Throw($"Map {mapName} has line count {LineCount} but line count >= {expectedMinLineCount.Value} is required.");
-
- if (LineCapacity < expectedMinLineCapacity)
- Throw($"Map {mapName} has line capacity {LineCapacity} but line capacity >= {expectedMinLineCapacity.Value} is required.");
-
- var name = ReadString(GetSpan(_header, 28));
- if (name != mapName)
- Throw($"Map {mapName} does not contain its map name at the expected location.");
-
- _lines = Enumerable.Range(0, (int)LineCount).Select(i
- => _file.CreateViewAccessor(headerLength + i * LineCapacity, LineCapacity, MemoryMappedFileAccess.ReadWrite))
- .ToArray();
-
- [DoesNotReturn]
- void Throw(string text)
- {
- _file.Dispose();
- _header?.Dispose();
- _disposed = true;
- throw new Exception(text);
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- _disposed = true;
- }
-
- protected static string ReadString(Span span)
- {
- if (span.IsEmpty)
- throw new Exception("String from empty span requested.");
-
- var termination = span.IndexOf((byte)0);
- if (termination < 0)
- throw new Exception("String in span is not terminated.");
-
- return Encoding.UTF8.GetString(span[..termination]);
- }
-
- protected static int WriteString(string text, Span span)
- {
- var bytes = Encoding.UTF8.GetBytes(text);
- var source = (Span)bytes;
- var length = source.Length + 1;
- if (length > span.Length)
- source = source[..(span.Length - 1)];
- source.CopyTo(span);
- span[bytes.Length] = 0;
- return source.Length + 1;
- }
-
- protected static int WriteSpan(ReadOnlySpan input, Span span)
- {
- var length = input.Length + 1;
- if (length > span.Length)
- input = input[..(span.Length - 1)];
-
- input.CopyTo(span);
- span[input.Length] = 0;
- return input.Length + 1;
- }
-
- protected Span GetLine(int i)
- {
- if (i < 0 || i > LineCount)
- return null;
-
- lock (_header)
- {
- var lineIdx = (CurrentLinePosition + i) & _lineMask;
- if (lineIdx > CurrentLineCount)
- return null;
-
- return GetSpan(_lines[lineIdx]);
- }
- }
-
-
- protected MemoryMappedViewAccessor GetCurrentLineLocking()
- {
- MemoryMappedViewAccessor view;
- lock (_header)
- {
- var currentLineCount = CurrentLineCount;
- if (currentLineCount == LineCount)
- {
- var currentLinePos = CurrentLinePosition;
- view = _lines[currentLinePos]!;
- CurrentLinePosition = (currentLinePos + 1) & _lineMask;
- }
- else
- {
- view = _lines[currentLineCount];
- ++CurrentLineCount;
- }
-
- ++TotalWrittenLines;
- _header.Flush();
- }
-
- return view;
- }
-
- protected static Span GetSpan(MemoryMappedViewAccessor accessor, int offset = 0)
- => GetSpan(accessor, offset, (int)accessor.Capacity - offset);
-
- protected static unsafe Span GetSpan(MemoryMappedViewAccessor accessor, int offset, int size)
- {
- byte* ptr = null;
- accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
- size = Math.Min(size, (int)accessor.Capacity - offset);
- if (size < 0)
- return [];
-
- var span = new Span(ptr + offset + accessor.PointerOffset, size);
- return span;
- }
-
- protected void Dispose(bool disposing)
- {
- if (_disposed)
- return;
-
- _header?.Dispose();
- foreach (var line in _lines)
- line?.Dispose();
- _file?.Dispose();
- }
-
- ~MemoryMappedBuffer()
- => Dispose(false);
-}
diff --git a/Penumbra.CrashHandler/Buffers/ModdedFileBuffer.cs b/Penumbra.CrashHandler/Buffers/ModdedFileBuffer.cs
deleted file mode 100644
index e4ee66d0..00000000
--- a/Penumbra.CrashHandler/Buffers/ModdedFileBuffer.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Nodes;
-
-namespace Penumbra.CrashHandler.Buffers;
-
-/// Only expose the write interface for the buffer.
-public interface IModdedFileBufferWriter
-{
- /// Write a line into the buffer with the given data.
- /// The address of the related character, if known.
- /// The name of the related character, anonymized or relying on index if unavailable, if known.
- /// The GUID of the associated collection.
- /// The file name as requested by the game.
- /// The actual modded file name loaded.
- public void WriteLine(nint characterAddress, ReadOnlySpan characterName, Guid collectionId, ReadOnlySpan requestedFileName,
- ReadOnlySpan actualFileName);
-}
-
-/// The full crash entry for a loaded modded file.
-public record struct ModdedFileLoadedEntry(
- double Age,
- DateTimeOffset Timestamp,
- int ThreadId,
- string CharacterName,
- string CharacterAddress,
- Guid CollectionId,
- string RequestedFileName,
- string ActualFileName) : ICrashDataEntry;
-
-internal sealed class ModdedFileBuffer : MemoryMappedBuffer, IModdedFileBufferWriter, IBufferReader
-{
- private const int _version = 1;
- private const int _lineCount = 128;
- private const int _lineCapacity = 1024;
- private const string _name = "Penumbra.ModdedFile";
-
- public void WriteLine(nint characterAddress, ReadOnlySpan characterName, Guid collectionId, ReadOnlySpan requestedFileName,
- ReadOnlySpan actualFileName)
- {
- var accessor = GetCurrentLineLocking();
- lock (accessor)
- {
- accessor.Write(0, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
- accessor.Write(8, Environment.CurrentManagedThreadId);
- accessor.Write(12, characterAddress);
- var span = GetSpan(accessor, 20, 16);
- collectionId.TryWriteBytes(span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- span = GetSpan(accessor, 36, 80);
- WriteSpan(characterName, span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- span = GetSpan(accessor, 116, 260);
- WriteSpan(requestedFileName, span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- span = GetSpan(accessor, 376);
- WriteSpan(actualFileName, span);
- accessor.SafeMemoryMappedViewHandle.ReleasePointer();
- }
- }
-
- public uint TotalCount
- => TotalWrittenLines;
-
- public IEnumerable GetLines(DateTimeOffset crashTime)
- {
- var lineCount = (int)CurrentLineCount;
- for (var i = lineCount - 1; i >= 0; --i)
- {
- var line = GetLine(i);
- var timestamp = DateTimeOffset.FromUnixTimeMilliseconds(BitConverter.ToInt64(line));
- var thread = BitConverter.ToInt32(line[8..]);
- var address = BitConverter.ToUInt64(line[12..]);
- var collectionId = new Guid(line[20..36]);
- var characterName = ReadString(line[36..]);
- var requestedFileName = ReadString(line[116..]);
- var actualFileName = ReadString(line[376..]);
- yield return new JsonObject()
- {
- [nameof(ModdedFileLoadedEntry.Age)] = (crashTime - timestamp).TotalSeconds,
- [nameof(ModdedFileLoadedEntry.Timestamp)] = timestamp,
- [nameof(ModdedFileLoadedEntry.ThreadId)] = thread,
- [nameof(ModdedFileLoadedEntry.CharacterName)] = characterName,
- [nameof(ModdedFileLoadedEntry.CharacterAddress)] = address.ToString("X"),
- [nameof(ModdedFileLoadedEntry.CollectionId)] = collectionId,
- [nameof(ModdedFileLoadedEntry.RequestedFileName)] = requestedFileName,
- [nameof(ModdedFileLoadedEntry.ActualFileName)] = actualFileName,
- };
- }
- }
-
- public static IBufferReader CreateReader(int pid)
- => new ModdedFileBuffer(false, pid);
-
- public static IModdedFileBufferWriter CreateWriter(int pid)
- => new ModdedFileBuffer(pid);
-
- private ModdedFileBuffer(bool writer, int pid)
- : base($"{_name}_{pid}_{_version}", _version)
- { }
-
- private ModdedFileBuffer(int pid)
- : base($"{_name}_{pid}_{_version}", _version, _lineCount, _lineCapacity)
- { }
-}
diff --git a/Penumbra.CrashHandler/CrashData.cs b/Penumbra.CrashHandler/CrashData.cs
deleted file mode 100644
index 55460548..00000000
--- a/Penumbra.CrashHandler/CrashData.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Penumbra.CrashHandler.Buffers;
-
-namespace Penumbra.CrashHandler;
-
-/// A base entry for crash data.
-public interface ICrashDataEntry
-{
- /// The timestamp of the event.
- DateTimeOffset Timestamp { get; }
-
- /// The thread invoking the event.
- int ThreadId { get; }
-
- /// The age of the event compared to the crash. (Redundantly with the timestamp)
- double Age { get; }
-}
-
-/// A full set of crash data.
-public class CrashData
-{
- /// The mode this data was obtained - manually or from a crash.
- public string Mode { get; set; } = "Unknown";
-
- /// The time this crash data was generated.
- public DateTimeOffset CrashTime { get; set; } = DateTimeOffset.UnixEpoch;
-
- /// Penumbra's Version when this crash data was created.
- public string Version { get; set; } = string.Empty;
-
- /// The Game's Version when this crash data was created.
- public string GameVersion { get; set; } = string.Empty;
-
- /// The FFXIV process ID when this data was generated.
- public int ProcessId { get; set; } = 0;
-
- /// The FFXIV Exit Code (if any) when this data was generated.
- public int ExitCode { get; set; } = 0;
-
- /// The total amount of characters loaded during this session.
- public int TotalCharactersLoaded { get; set; } = 0;
-
- /// The total amount of modded files loaded during this session.
- public int TotalModdedFilesLoaded { get; set; } = 0;
-
- /// The total amount of vfx functions invoked during this session.
- public int TotalVFXFuncsInvoked { get; set; } = 0;
-
- /// The last character loaded before this crash data was generated.
- public CharacterLoadedEntry? LastCharacterLoaded
- => LastCharactersLoaded.Count == 0 ? default : LastCharactersLoaded[0];
-
- /// The last modded file loaded before this crash data was generated.
- public ModdedFileLoadedEntry? LastModdedFileLoaded
- => LastModdedFilesLoaded.Count == 0 ? default : LastModdedFilesLoaded[0];
-
- /// The last vfx function invoked before this crash data was generated.
- public VfxFuncInvokedEntry? LastVfxFuncInvoked
- => LastVFXFuncsInvoked.Count == 0 ? default : LastVFXFuncsInvoked[0];
-
- /// A collection of the last few characters loaded before this crash data was generated.
- public List LastCharactersLoaded { get; set; } = [];
-
- /// A collection of the last few modded files loaded before this crash data was generated.
- public List LastModdedFilesLoaded { get; set; } = [];
-
- /// A collection of the last few vfx functions invoked before this crash data was generated.
- public List LastVFXFuncsInvoked { get; set; } = [];
-}
diff --git a/Penumbra.CrashHandler/GameEventLogReader.cs b/Penumbra.CrashHandler/GameEventLogReader.cs
deleted file mode 100644
index 8a7f53f8..00000000
--- a/Penumbra.CrashHandler/GameEventLogReader.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.Json.Nodes;
-using Penumbra.CrashHandler.Buffers;
-
-namespace Penumbra.CrashHandler;
-
-public interface IBufferReader
-{
- public uint TotalCount { get; }
- public IEnumerable GetLines(DateTimeOffset crashTime);
-}
-
-public sealed class GameEventLogReader(int pid) : IDisposable
-{
- public readonly (IBufferReader Reader, string TypeSingular, string TypePlural)[] Readers =
- [
- (CharacterBaseBuffer.CreateReader(pid), "CharacterLoaded", "CharactersLoaded"),
- (ModdedFileBuffer.CreateReader(pid), "ModdedFileLoaded", "ModdedFilesLoaded"),
- (AnimationInvocationBuffer.CreateReader(pid), "VFXFuncInvoked", "VFXFuncsInvoked"),
- ];
-
- public void Dispose()
- {
- foreach (var (reader, _, _) in Readers)
- (reader as IDisposable)?.Dispose();
- }
-
-
- public JsonObject Dump(string mode, int processId, int exitCode, string version, string gameVersion)
- {
- var crashTime = DateTimeOffset.UtcNow;
- var obj = new JsonObject
- {
- [nameof(CrashData.Mode)] = mode,
- [nameof(CrashData.CrashTime)] = DateTimeOffset.UtcNow,
- [nameof(CrashData.ProcessId)] = processId,
- [nameof(CrashData.ExitCode)] = exitCode,
- [nameof(CrashData.Version)] = version,
- [nameof(CrashData.GameVersion)] = gameVersion,
- };
-
- foreach (var (reader, singular, _) in Readers)
- obj["Last" + singular] = reader.GetLines(crashTime).FirstOrDefault();
-
- foreach (var (reader, _, plural) in Readers)
- {
- obj["Total" + plural] = reader.TotalCount;
- var array = new JsonArray();
- foreach (var file in reader.GetLines(crashTime))
- array.Add(file);
- obj["Last" + plural] = array;
- }
-
- return obj;
- }
-}
diff --git a/Penumbra.CrashHandler/GameEventLogWriter.cs b/Penumbra.CrashHandler/GameEventLogWriter.cs
deleted file mode 100644
index 915c59a2..00000000
--- a/Penumbra.CrashHandler/GameEventLogWriter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using Penumbra.CrashHandler.Buffers;
-
-namespace Penumbra.CrashHandler;
-
-public sealed class GameEventLogWriter(int pid) : IDisposable
-{
- public readonly ICharacterBaseBufferWriter CharacterBase = CharacterBaseBuffer.CreateWriter(pid);
- public readonly IModdedFileBufferWriter FileLoaded = ModdedFileBuffer.CreateWriter(pid);
- public readonly IAnimationInvocationBufferWriter AnimationFuncInvoked = AnimationInvocationBuffer.CreateWriter(pid);
-
- public void Dispose()
- {
- (CharacterBase as IDisposable)?.Dispose();
- (FileLoaded as IDisposable)?.Dispose();
- (AnimationFuncInvoked as IDisposable)?.Dispose();
- }
-}
diff --git a/Penumbra.CrashHandler/Penumbra.CrashHandler.csproj b/Penumbra.CrashHandler/Penumbra.CrashHandler.csproj
deleted file mode 100644
index e07bb745..00000000
--- a/Penumbra.CrashHandler/Penumbra.CrashHandler.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Exe
-
-
-
- embedded
-
-
-
- embedded
-
-
-
- false
-
-
-
diff --git a/Penumbra.CrashHandler/Program.cs b/Penumbra.CrashHandler/Program.cs
deleted file mode 100644
index 38c176a6..00000000
--- a/Penumbra.CrashHandler/Program.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Text.Json;
-
-namespace Penumbra.CrashHandler;
-
-public class CrashHandler
-{
- public static void Main(string[] args)
- {
- if (args.Length < 4 || !int.TryParse(args[1], out var pid))
- return;
-
- try
- {
- using var reader = new GameEventLogReader(pid);
- var parent = Process.GetProcessById(pid);
- using var handle = parent.SafeHandle;
- parent.WaitForExit();
- int exitCode;
- try
- {
- exitCode = parent.ExitCode;
- }
- catch
- {
- exitCode = -1;
- }
-
- var obj = reader.Dump("Crash", pid, exitCode, args[2], args[3]);
- using var fs = File.Open(args[0], FileMode.Create);
- using var w = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true });
- obj.WriteTo(w, new JsonSerializerOptions() { WriteIndented = true });
- }
- catch (Exception ex)
- {
- File.WriteAllText(args[0], $"{DateTime.UtcNow} {pid} {ex}");
- }
- }
-}
diff --git a/Penumbra.CrashHandler/packages.lock.json b/Penumbra.CrashHandler/packages.lock.json
deleted file mode 100644
index 0a160ea5..00000000
--- a/Penumbra.CrashHandler/packages.lock.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "version": 1,
- "dependencies": {
- "net10.0-windows7.0": {
- "DotNet.ReproducibleBuilds": {
- "type": "Direct",
- "requested": "[1.2.39, )",
- "resolved": "1.2.39",
- "contentHash": "fcFN01tDTIQqDuTwr1jUQK/geofiwjG5DycJQOnC72i1SsLAk1ELe+apBOuZ11UMQG8YKFZG1FgvjZPbqHyatg=="
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Penumbra.GameData b/Penumbra.GameData
deleted file mode 160000
index 0e973ed6..00000000
--- a/Penumbra.GameData
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 0e973ed6eace6afd31cd298f8c58f76fa8d5ef60
diff --git a/Penumbra.GameData/Enums/BodySlot.cs b/Penumbra.GameData/Enums/BodySlot.cs
new file mode 100644
index 00000000..0e1220ce
--- /dev/null
+++ b/Penumbra.GameData/Enums/BodySlot.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum BodySlot : byte
+ {
+ Unknown,
+ Hair,
+ Face,
+ Tail,
+ Body,
+ Zear,
+ }
+
+ public static class BodySlotEnumExtension
+ {
+ public static string ToSuffix( this BodySlot value )
+ {
+ return value switch
+ {
+ BodySlot.Zear => "zear",
+ BodySlot.Face => "face",
+ BodySlot.Hair => "hair",
+ BodySlot.Body => "body",
+ BodySlot.Tail => "tail",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+ }
+
+ public static partial class Names
+ {
+ public static readonly Dictionary< string, BodySlot > StringToBodySlot = new()
+ {
+ { BodySlot.Zear.ToSuffix(), BodySlot.Zear },
+ { BodySlot.Face.ToSuffix(), BodySlot.Face },
+ { BodySlot.Hair.ToSuffix(), BodySlot.Hair },
+ { BodySlot.Body.ToSuffix(), BodySlot.Body },
+ { BodySlot.Tail.ToSuffix(), BodySlot.Tail },
+ };
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/ChangedItemType.cs b/Penumbra.GameData/Enums/ChangedItemType.cs
new file mode 100644
index 00000000..fa33382d
--- /dev/null
+++ b/Penumbra.GameData/Enums/ChangedItemType.cs
@@ -0,0 +1,40 @@
+using System;
+using Lumina.Excel.GeneratedSheets;
+using Action = Lumina.Excel.GeneratedSheets.Action;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum ChangedItemType
+ {
+ None,
+ Item,
+ Action,
+ Customization,
+ }
+
+ public static class ChangedItemExtensions
+ {
+ public static (ChangedItemType, uint) ChangedItemToTypeAndId( object? item )
+ {
+ return item switch
+ {
+ null => ( ChangedItemType.None, 0 ),
+ Item i => ( ChangedItemType.Item, i.RowId ),
+ Action a => ( ChangedItemType.Action, a.RowId ),
+ _ => ( ChangedItemType.Customization, 0 ),
+ };
+ }
+
+ public static object? GetObject( this ChangedItemType type, uint id )
+ {
+ return type switch
+ {
+ ChangedItemType.None => null,
+ ChangedItemType.Item => ObjectIdentification.DataManager?.GetExcelSheet< Item >()?.GetRow( id ),
+ ChangedItemType.Action => ObjectIdentification.DataManager?.GetExcelSheet< Action >()?.GetRow( id ),
+ ChangedItemType.Customization => null,
+ _ => throw new ArgumentOutOfRangeException( nameof( type ), type, null )
+ };
+ }
+ }
+}
diff --git a/Penumbra.GameData/Enums/CustomizationType.cs b/Penumbra.GameData/Enums/CustomizationType.cs
new file mode 100644
index 00000000..60cf23dd
--- /dev/null
+++ b/Penumbra.GameData/Enums/CustomizationType.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum CustomizationType : byte
+ {
+ Unknown,
+ Body,
+ Tail,
+ Face,
+ Iris,
+ Accessory,
+ Hair,
+ Zear,
+ DecalFace,
+ DecalEquip,
+ Skin,
+ Etc,
+ }
+
+ public static class CustomizationTypeEnumExtension
+ {
+ public static string ToSuffix( this CustomizationType value )
+ {
+ return value switch
+ {
+ CustomizationType.Body => "top",
+ CustomizationType.Face => "fac",
+ CustomizationType.Iris => "iri",
+ CustomizationType.Accessory => "acc",
+ CustomizationType.Hair => "hir",
+ CustomizationType.Tail => "til",
+ CustomizationType.Zear => "zer",
+ CustomizationType.Etc => "etc",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+ }
+
+ public static partial class Names
+ {
+ public static readonly Dictionary< string, CustomizationType > SuffixToCustomizationType = new()
+ {
+ { CustomizationType.Body.ToSuffix(), CustomizationType.Body },
+ { CustomizationType.Face.ToSuffix(), CustomizationType.Face },
+ { CustomizationType.Iris.ToSuffix(), CustomizationType.Iris },
+ { CustomizationType.Accessory.ToSuffix(), CustomizationType.Accessory },
+ { CustomizationType.Hair.ToSuffix(), CustomizationType.Hair },
+ { CustomizationType.Tail.ToSuffix(), CustomizationType.Tail },
+ { CustomizationType.Zear.ToSuffix(), CustomizationType.Zear },
+ { CustomizationType.Etc.ToSuffix(), CustomizationType.Etc },
+ };
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/EquipSlot.cs b/Penumbra.GameData/Enums/EquipSlot.cs
new file mode 100644
index 00000000..061787e6
--- /dev/null
+++ b/Penumbra.GameData/Enums/EquipSlot.cs
@@ -0,0 +1,125 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum EquipSlot : byte
+ {
+ Unknown = 0,
+ MainHand = 1,
+ OffHand = 2,
+ Head = 3,
+ Body = 4,
+ Hands = 5,
+ Belt = 6,
+ Legs = 7,
+ Feet = 8,
+ Ears = 9,
+ Neck = 10,
+ Wrists = 11,
+ RFinger = 12,
+ BothHand = 13,
+ LFinger = 14, // Not officially existing, means "weapon could be equipped in either hand" for the game.
+ HeadBody = 15,
+ BodyHandsLegsFeet = 16,
+ SoulCrystal = 17,
+ LegsFeet = 18,
+ FullBody = 19,
+ BodyHands = 20,
+ BodyLegsFeet = 21,
+ All = 22, // Not officially existing
+ }
+
+ public static class EquipSlotEnumExtension
+ {
+ public static string ToSuffix( this EquipSlot value )
+ {
+ return value switch
+ {
+ EquipSlot.Head => "met",
+ EquipSlot.Hands => "glv",
+ EquipSlot.Legs => "dwn",
+ EquipSlot.Feet => "sho",
+ EquipSlot.Body => "top",
+ EquipSlot.Ears => "ear",
+ EquipSlot.Neck => "nek",
+ EquipSlot.RFinger => "rir",
+ EquipSlot.LFinger => "ril",
+ EquipSlot.Wrists => "wrs",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static EquipSlot ToSlot( this EquipSlot value )
+ {
+ return value switch
+ {
+ EquipSlot.MainHand => EquipSlot.MainHand,
+ EquipSlot.OffHand => EquipSlot.OffHand,
+ EquipSlot.Head => EquipSlot.Head,
+ EquipSlot.Body => EquipSlot.Body,
+ EquipSlot.Hands => EquipSlot.Hands,
+ EquipSlot.Belt => EquipSlot.Belt,
+ EquipSlot.Legs => EquipSlot.Legs,
+ EquipSlot.Feet => EquipSlot.Feet,
+ EquipSlot.Ears => EquipSlot.Ears,
+ EquipSlot.Neck => EquipSlot.Neck,
+ EquipSlot.Wrists => EquipSlot.Wrists,
+ EquipSlot.RFinger => EquipSlot.RFinger,
+ EquipSlot.BothHand => EquipSlot.MainHand,
+ EquipSlot.LFinger => EquipSlot.RFinger,
+ EquipSlot.HeadBody => EquipSlot.Body,
+ EquipSlot.BodyHandsLegsFeet => EquipSlot.Body,
+ EquipSlot.SoulCrystal => EquipSlot.SoulCrystal,
+ EquipSlot.LegsFeet => EquipSlot.Legs,
+ EquipSlot.FullBody => EquipSlot.Body,
+ EquipSlot.BodyHands => EquipSlot.Body,
+ EquipSlot.BodyLegsFeet => EquipSlot.Body,
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static bool IsEquipment( this EquipSlot value )
+ {
+ return value switch
+ {
+ EquipSlot.Head => true,
+ EquipSlot.Hands => true,
+ EquipSlot.Legs => true,
+ EquipSlot.Feet => true,
+ EquipSlot.Body => true,
+ _ => false,
+ };
+ }
+
+ public static bool IsAccessory( this EquipSlot value )
+ {
+ return value switch
+ {
+ EquipSlot.Ears => true,
+ EquipSlot.Neck => true,
+ EquipSlot.RFinger => true,
+ EquipSlot.LFinger => true,
+ EquipSlot.Wrists => true,
+ _ => false,
+ };
+ }
+ }
+
+ public static partial class Names
+ {
+ public static readonly Dictionary< string, EquipSlot > SuffixToEquipSlot = new()
+ {
+ { EquipSlot.Head.ToSuffix(), EquipSlot.Head },
+ { EquipSlot.Hands.ToSuffix(), EquipSlot.Hands },
+ { EquipSlot.Legs.ToSuffix(), EquipSlot.Legs },
+ { EquipSlot.Feet.ToSuffix(), EquipSlot.Feet },
+ { EquipSlot.Body.ToSuffix(), EquipSlot.Body },
+ { EquipSlot.Ears.ToSuffix(), EquipSlot.Ears },
+ { EquipSlot.Neck.ToSuffix(), EquipSlot.Neck },
+ { EquipSlot.RFinger.ToSuffix(), EquipSlot.RFinger },
+ { EquipSlot.LFinger.ToSuffix(), EquipSlot.LFinger },
+ { EquipSlot.Wrists.ToSuffix(), EquipSlot.Wrists },
+ };
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/FileType.cs b/Penumbra.GameData/Enums/FileType.cs
new file mode 100644
index 00000000..e326ef17
--- /dev/null
+++ b/Penumbra.GameData/Enums/FileType.cs
@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum FileType : byte
+ {
+ Unknown,
+ Sound,
+ Imc,
+ Vfx,
+ Animation,
+ Pap,
+ MetaInfo,
+ Material,
+ Texture,
+ Model,
+ Shader,
+ Font,
+ Environment,
+ }
+
+ public static partial class Names
+ {
+ public static readonly Dictionary< string, FileType > ExtensionToFileType = new()
+ {
+ { ".mdl", FileType.Model },
+ { ".tex", FileType.Texture },
+ { ".mtrl", FileType.Material },
+ { ".atex", FileType.Animation },
+ { ".avfx", FileType.Vfx },
+ { ".scd", FileType.Sound },
+ { ".imc", FileType.Imc },
+ { ".pap", FileType.Pap },
+ { ".eqp", FileType.MetaInfo },
+ { ".eqdp", FileType.MetaInfo },
+ { ".est", FileType.MetaInfo },
+ { ".exd", FileType.MetaInfo },
+ { ".exh", FileType.MetaInfo },
+ { ".shpk", FileType.Shader },
+ { ".shcd", FileType.Shader },
+ { ".fdt", FileType.Font },
+ { ".envb", FileType.Environment },
+ };
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/MouseButton.cs b/Penumbra.GameData/Enums/MouseButton.cs
new file mode 100644
index 00000000..99948d7c
--- /dev/null
+++ b/Penumbra.GameData/Enums/MouseButton.cs
@@ -0,0 +1,10 @@
+namespace Penumbra.GameData.Enums
+{
+ public enum MouseButton
+ {
+ None,
+ Left,
+ Right,
+ Middle,
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/ObjectType.cs b/Penumbra.GameData/Enums/ObjectType.cs
new file mode 100644
index 00000000..8b62e42b
--- /dev/null
+++ b/Penumbra.GameData/Enums/ObjectType.cs
@@ -0,0 +1,21 @@
+namespace Penumbra.GameData.Enums
+{
+ public enum ObjectType : byte
+ {
+ Unknown,
+ Vfx,
+ DemiHuman,
+ Accessory,
+ World,
+ Housing,
+ Monster,
+ Icon,
+ LoadingScreen,
+ Map,
+ Interface,
+ Equipment,
+ Character,
+ Weapon,
+ Font,
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/Race.cs b/Penumbra.GameData/Enums/Race.cs
new file mode 100644
index 00000000..8221a625
--- /dev/null
+++ b/Penumbra.GameData/Enums/Race.cs
@@ -0,0 +1,453 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum Race : byte
+ {
+ Unknown,
+ Hyur,
+ Elezen,
+ Lalafell,
+ Miqote,
+ Roegadyn,
+ AuRa,
+ Hrothgar,
+ Viera,
+ }
+
+ public enum Gender : byte
+ {
+ Unknown,
+ Male,
+ Female,
+ MaleNpc,
+ FemaleNpc,
+ }
+
+ public enum ModelRace : byte
+ {
+ Unknown,
+ Midlander,
+ Highlander,
+ Elezen,
+ Lalafell,
+ Miqote,
+ Roegadyn,
+ AuRa,
+ Hrothgar,
+ Viera,
+ }
+
+ public enum SubRace : byte
+ {
+ Unknown,
+ Midlander,
+ Highlander,
+ Wildwood,
+ Duskwight,
+ Plainsfolk,
+ Dunesfolk,
+ SeekerOfTheSun,
+ KeeperOfTheMoon,
+ Seawolf,
+ Hellsguard,
+ Raen,
+ Xaela,
+ Helion,
+ Lost,
+ Rava,
+ Veena,
+ }
+
+ // The combined gender-race-npc numerical code as used by the game.
+ public enum GenderRace : ushort
+ {
+ Unknown = 0,
+ MidlanderMale = 0101,
+ MidlanderMaleNpc = 0104,
+ MidlanderFemale = 0201,
+ MidlanderFemaleNpc = 0204,
+ HighlanderMale = 0301,
+ HighlanderMaleNpc = 0304,
+ HighlanderFemale = 0401,
+ HighlanderFemaleNpc = 0404,
+ ElezenMale = 0501,
+ ElezenMaleNpc = 0504,
+ ElezenFemale = 0601,
+ ElezenFemaleNpc = 0604,
+ MiqoteMale = 0701,
+ MiqoteMaleNpc = 0704,
+ MiqoteFemale = 0801,
+ MiqoteFemaleNpc = 0804,
+ RoegadynMale = 0901,
+ RoegadynMaleNpc = 0904,
+ RoegadynFemale = 1001,
+ RoegadynFemaleNpc = 1004,
+ LalafellMale = 1101,
+ LalafellMaleNpc = 1104,
+ LalafellFemale = 1201,
+ LalafellFemaleNpc = 1204,
+ AuRaMale = 1301,
+ AuRaMaleNpc = 1304,
+ AuRaFemale = 1401,
+ AuRaFemaleNpc = 1404,
+ HrothgarMale = 1501,
+ HrothgarMaleNpc = 1504,
+ VieraFemale = 1801,
+ VieraFemaleNpc = 1804,
+ UnknownMaleNpc = 9104,
+ UnknownFemaleNpc = 9204,
+ }
+
+ public static class RaceEnumExtensions
+ {
+ public static int ToRspIndex( this SubRace subRace )
+ {
+ return subRace switch
+ {
+ SubRace.Midlander => 0,
+ SubRace.Highlander => 1,
+ SubRace.Wildwood => 10,
+ SubRace.Duskwight => 11,
+ SubRace.Plainsfolk => 20,
+ SubRace.Dunesfolk => 21,
+ SubRace.SeekerOfTheSun => 30,
+ SubRace.KeeperOfTheMoon => 31,
+ SubRace.Seawolf => 40,
+ SubRace.Hellsguard => 41,
+ SubRace.Raen => 50,
+ SubRace.Xaela => 51,
+ SubRace.Helion => 60,
+ SubRace.Lost => 61,
+ SubRace.Rava => 70,
+ SubRace.Veena => 71,
+ _ => throw new ArgumentOutOfRangeException( nameof( subRace ), subRace, null ),
+ };
+ }
+
+ public static Race ToRace( this ModelRace race )
+ {
+ return race switch
+ {
+ ModelRace.Unknown => Race.Unknown,
+ ModelRace.Midlander => Race.Hyur,
+ ModelRace.Highlander => Race.Hyur,
+ ModelRace.Elezen => Race.Elezen,
+ ModelRace.Lalafell => Race.Lalafell,
+ ModelRace.Miqote => Race.Miqote,
+ ModelRace.Roegadyn => Race.Roegadyn,
+ ModelRace.AuRa => Race.AuRa,
+ ModelRace.Hrothgar => Race.Hrothgar,
+ ModelRace.Viera => Race.Viera,
+ _ => throw new ArgumentOutOfRangeException( nameof( race ), race, null ),
+ };
+ }
+
+ public static Race ToRace( this SubRace subRace )
+ {
+ return subRace switch
+ {
+ SubRace.Unknown => Race.Unknown,
+ SubRace.Midlander => Race.Hyur,
+ SubRace.Highlander => Race.Hyur,
+ SubRace.Wildwood => Race.Elezen,
+ SubRace.Duskwight => Race.Elezen,
+ SubRace.Plainsfolk => Race.Lalafell,
+ SubRace.Dunesfolk => Race.Lalafell,
+ SubRace.SeekerOfTheSun => Race.Miqote,
+ SubRace.KeeperOfTheMoon => Race.Miqote,
+ SubRace.Seawolf => Race.Roegadyn,
+ SubRace.Hellsguard => Race.Roegadyn,
+ SubRace.Raen => Race.AuRa,
+ SubRace.Xaela => Race.AuRa,
+ SubRace.Helion => Race.Hrothgar,
+ SubRace.Lost => Race.Hrothgar,
+ SubRace.Rava => Race.Viera,
+ SubRace.Veena => Race.Viera,
+ _ => throw new ArgumentOutOfRangeException( nameof( subRace ), subRace, null ),
+ };
+ }
+
+ public static string ToName( this ModelRace modelRace )
+ {
+ return modelRace switch
+ {
+ ModelRace.Midlander => SubRace.Midlander.ToName(),
+ ModelRace.Highlander => SubRace.Highlander.ToName(),
+ ModelRace.Elezen => Race.Elezen.ToName(),
+ ModelRace.Lalafell => Race.Lalafell.ToName(),
+ ModelRace.Miqote => Race.Miqote.ToName(),
+ ModelRace.Roegadyn => Race.Roegadyn.ToName(),
+ ModelRace.AuRa => Race.AuRa.ToName(),
+ ModelRace.Hrothgar => Race.Hrothgar.ToName(),
+ ModelRace.Viera => Race.Viera.ToName(),
+ _ => throw new ArgumentOutOfRangeException( nameof( modelRace ), modelRace, null ),
+ };
+ }
+
+ public static string ToName( this Race race )
+ {
+ return race switch
+ {
+ Race.Hyur => "Hyur",
+ Race.Elezen => "Elezen",
+ Race.Lalafell => "Lalafell",
+ Race.Miqote => "Miqo'te",
+ Race.Roegadyn => "Roegadyn",
+ Race.AuRa => "Au Ra",
+ Race.Hrothgar => "Hrothgar",
+ Race.Viera => "Viera",
+ _ => throw new ArgumentOutOfRangeException( nameof( race ), race, null ),
+ };
+ }
+
+ public static string ToName( this Gender gender )
+ {
+ return gender switch
+ {
+ Gender.Male => "Male",
+ Gender.Female => "Female",
+ Gender.MaleNpc => "Male (NPC)",
+ Gender.FemaleNpc => "Female (NPC)",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static string ToName( this SubRace subRace )
+ {
+ return subRace switch
+ {
+ SubRace.Midlander => "Midlander",
+ SubRace.Highlander => "Highlander",
+ SubRace.Wildwood => "Wildwood",
+ SubRace.Duskwight => "Duskwright",
+ SubRace.Plainsfolk => "Plainsfolk",
+ SubRace.Dunesfolk => "Dunesfolk",
+ SubRace.SeekerOfTheSun => "Seeker Of The Sun",
+ SubRace.KeeperOfTheMoon => "Keeper Of The Moon",
+ SubRace.Seawolf => "Seawolf",
+ SubRace.Hellsguard => "Hellsguard",
+ SubRace.Raen => "Raen",
+ SubRace.Xaela => "Xaela",
+ SubRace.Helion => "Hellion",
+ SubRace.Lost => "Lost",
+ SubRace.Rava => "Rava",
+ SubRace.Veena => "Veena",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static bool FitsRace( this SubRace subRace, Race race )
+ => subRace.ToRace() == race;
+
+ public static byte ToByte( this Gender gender, ModelRace modelRace )
+ => ( byte )( ( int )gender | ( ( int )modelRace << 3 ) );
+
+ public static byte ToByte( this ModelRace modelRace, Gender gender )
+ => gender.ToByte( modelRace );
+
+ public static byte ToByte( this GenderRace value )
+ {
+ var (gender, race) = value.Split();
+ return gender.ToByte( race );
+ }
+
+ public static (Gender, ModelRace) Split( this GenderRace value )
+ {
+ return value switch
+ {
+ GenderRace.Unknown => ( Gender.Unknown, ModelRace.Unknown ),
+ GenderRace.MidlanderMale => ( Gender.Male, ModelRace.Midlander ),
+ GenderRace.MidlanderMaleNpc => ( Gender.MaleNpc, ModelRace.Midlander ),
+ GenderRace.MidlanderFemale => ( Gender.Female, ModelRace.Midlander ),
+ GenderRace.MidlanderFemaleNpc => ( Gender.FemaleNpc, ModelRace.Midlander ),
+ GenderRace.HighlanderMale => ( Gender.Male, ModelRace.Highlander ),
+ GenderRace.HighlanderMaleNpc => ( Gender.MaleNpc, ModelRace.Highlander ),
+ GenderRace.HighlanderFemale => ( Gender.Female, ModelRace.Highlander ),
+ GenderRace.HighlanderFemaleNpc => ( Gender.FemaleNpc, ModelRace.Highlander ),
+ GenderRace.ElezenMale => ( Gender.Male, ModelRace.Elezen ),
+ GenderRace.ElezenMaleNpc => ( Gender.MaleNpc, ModelRace.Elezen ),
+ GenderRace.ElezenFemale => ( Gender.Female, ModelRace.Elezen ),
+ GenderRace.ElezenFemaleNpc => ( Gender.FemaleNpc, ModelRace.Elezen ),
+ GenderRace.LalafellMale => ( Gender.Male, ModelRace.Lalafell ),
+ GenderRace.LalafellMaleNpc => ( Gender.MaleNpc, ModelRace.Lalafell ),
+ GenderRace.LalafellFemale => ( Gender.Female, ModelRace.Lalafell ),
+ GenderRace.LalafellFemaleNpc => ( Gender.FemaleNpc, ModelRace.Lalafell ),
+ GenderRace.MiqoteMale => ( Gender.Male, ModelRace.Miqote ),
+ GenderRace.MiqoteMaleNpc => ( Gender.MaleNpc, ModelRace.Miqote ),
+ GenderRace.MiqoteFemale => ( Gender.Female, ModelRace.Miqote ),
+ GenderRace.MiqoteFemaleNpc => ( Gender.FemaleNpc, ModelRace.Miqote ),
+ GenderRace.RoegadynMale => ( Gender.Male, ModelRace.Roegadyn ),
+ GenderRace.RoegadynMaleNpc => ( Gender.MaleNpc, ModelRace.Roegadyn ),
+ GenderRace.RoegadynFemale => ( Gender.Female, ModelRace.Roegadyn ),
+ GenderRace.RoegadynFemaleNpc => ( Gender.FemaleNpc, ModelRace.Roegadyn ),
+ GenderRace.AuRaMale => ( Gender.Male, ModelRace.AuRa ),
+ GenderRace.AuRaMaleNpc => ( Gender.MaleNpc, ModelRace.AuRa ),
+ GenderRace.AuRaFemale => ( Gender.Female, ModelRace.AuRa ),
+ GenderRace.AuRaFemaleNpc => ( Gender.FemaleNpc, ModelRace.AuRa ),
+ GenderRace.HrothgarMale => ( Gender.Male, ModelRace.Hrothgar ),
+ GenderRace.HrothgarMaleNpc => ( Gender.MaleNpc, ModelRace.Hrothgar ),
+ GenderRace.VieraFemale => ( Gender.Female, ModelRace.Viera ),
+ GenderRace.VieraFemaleNpc => ( Gender.FemaleNpc, ModelRace.Viera ),
+ GenderRace.UnknownMaleNpc => ( Gender.MaleNpc, ModelRace.Unknown ),
+ GenderRace.UnknownFemaleNpc => ( Gender.FemaleNpc, ModelRace.Unknown ),
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static bool IsValid( this GenderRace value )
+ => value != GenderRace.Unknown && Enum.IsDefined( typeof( GenderRace ), value );
+
+ public static string ToRaceCode( this GenderRace value )
+ {
+ return value switch
+ {
+ GenderRace.MidlanderMale => "0101",
+ GenderRace.MidlanderMaleNpc => "0104",
+ GenderRace.MidlanderFemale => "0201",
+ GenderRace.MidlanderFemaleNpc => "0204",
+ GenderRace.HighlanderMale => "0301",
+ GenderRace.HighlanderMaleNpc => "0304",
+ GenderRace.HighlanderFemale => "0401",
+ GenderRace.HighlanderFemaleNpc => "0404",
+ GenderRace.ElezenMale => "0501",
+ GenderRace.ElezenMaleNpc => "0504",
+ GenderRace.ElezenFemale => "0601",
+ GenderRace.ElezenFemaleNpc => "0604",
+ GenderRace.MiqoteMale => "0701",
+ GenderRace.MiqoteMaleNpc => "0704",
+ GenderRace.MiqoteFemale => "0801",
+ GenderRace.MiqoteFemaleNpc => "0804",
+ GenderRace.RoegadynMale => "0901",
+ GenderRace.RoegadynMaleNpc => "0904",
+ GenderRace.RoegadynFemale => "1001",
+ GenderRace.RoegadynFemaleNpc => "1004",
+ GenderRace.LalafellMale => "1101",
+ GenderRace.LalafellMaleNpc => "1104",
+ GenderRace.LalafellFemale => "1201",
+ GenderRace.LalafellFemaleNpc => "1204",
+ GenderRace.AuRaMale => "1301",
+ GenderRace.AuRaMaleNpc => "1304",
+ GenderRace.AuRaFemale => "1401",
+ GenderRace.AuRaFemaleNpc => "1404",
+ GenderRace.HrothgarMale => "1501",
+ GenderRace.HrothgarMaleNpc => "1504",
+ GenderRace.VieraFemale => "1801",
+ GenderRace.VieraFemaleNpc => "1804",
+ GenderRace.UnknownMaleNpc => "9104",
+ GenderRace.UnknownFemaleNpc => "9204",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+ }
+
+ public static partial class Names
+ {
+ public static GenderRace GenderRaceFromCode( string code )
+ {
+ return code switch
+ {
+ "0101" => GenderRace.MidlanderMale,
+ "0104" => GenderRace.MidlanderMaleNpc,
+ "0201" => GenderRace.MidlanderFemale,
+ "0204" => GenderRace.MidlanderFemaleNpc,
+ "0301" => GenderRace.HighlanderMale,
+ "0304" => GenderRace.HighlanderMaleNpc,
+ "0401" => GenderRace.HighlanderFemale,
+ "0404" => GenderRace.HighlanderFemaleNpc,
+ "0501" => GenderRace.ElezenMale,
+ "0504" => GenderRace.ElezenMaleNpc,
+ "0601" => GenderRace.ElezenFemale,
+ "0604" => GenderRace.ElezenFemaleNpc,
+ "0701" => GenderRace.MiqoteMale,
+ "0704" => GenderRace.MiqoteMaleNpc,
+ "0801" => GenderRace.MiqoteFemale,
+ "0804" => GenderRace.MiqoteFemaleNpc,
+ "0901" => GenderRace.RoegadynMale,
+ "0904" => GenderRace.RoegadynMaleNpc,
+ "1001" => GenderRace.RoegadynFemale,
+ "1004" => GenderRace.RoegadynFemaleNpc,
+ "1101" => GenderRace.LalafellMale,
+ "1104" => GenderRace.LalafellMaleNpc,
+ "1201" => GenderRace.LalafellFemale,
+ "1204" => GenderRace.LalafellFemaleNpc,
+ "1301" => GenderRace.AuRaMale,
+ "1304" => GenderRace.AuRaMaleNpc,
+ "1401" => GenderRace.AuRaFemale,
+ "1404" => GenderRace.AuRaFemaleNpc,
+ "1501" => GenderRace.HrothgarMale,
+ "1504" => GenderRace.HrothgarMaleNpc,
+ "1801" => GenderRace.VieraFemale,
+ "1804" => GenderRace.VieraFemaleNpc,
+ "9104" => GenderRace.UnknownMaleNpc,
+ "9204" => GenderRace.UnknownFemaleNpc,
+ _ => throw new KeyNotFoundException(),
+ };
+ }
+
+ public static GenderRace GenderRaceFromByte( byte value )
+ {
+ var gender = ( Gender )( value & 0b111 );
+ var race = ( ModelRace )( value >> 3 );
+ return CombinedRace( gender, race );
+ }
+
+ public static GenderRace CombinedRace( Gender gender, ModelRace modelRace )
+ {
+ return gender switch
+ {
+ Gender.Male => modelRace switch
+ {
+ ModelRace.Midlander => GenderRace.MidlanderMale,
+ ModelRace.Highlander => GenderRace.HighlanderMale,
+ ModelRace.Elezen => GenderRace.ElezenMale,
+ ModelRace.Lalafell => GenderRace.LalafellMale,
+ ModelRace.Miqote => GenderRace.MiqoteMale,
+ ModelRace.Roegadyn => GenderRace.RoegadynMale,
+ ModelRace.AuRa => GenderRace.AuRaMale,
+ ModelRace.Hrothgar => GenderRace.HrothgarMale,
+ _ => GenderRace.Unknown,
+ },
+ Gender.MaleNpc => modelRace switch
+ {
+ ModelRace.Midlander => GenderRace.MidlanderMaleNpc,
+ ModelRace.Highlander => GenderRace.HighlanderMaleNpc,
+ ModelRace.Elezen => GenderRace.ElezenMaleNpc,
+ ModelRace.Lalafell => GenderRace.LalafellMaleNpc,
+ ModelRace.Miqote => GenderRace.MiqoteMaleNpc,
+ ModelRace.Roegadyn => GenderRace.RoegadynMaleNpc,
+ ModelRace.AuRa => GenderRace.AuRaMaleNpc,
+ ModelRace.Hrothgar => GenderRace.HrothgarMaleNpc,
+ _ => GenderRace.Unknown,
+ },
+ Gender.Female => modelRace switch
+ {
+ ModelRace.Midlander => GenderRace.MidlanderFemale,
+ ModelRace.Highlander => GenderRace.HighlanderFemale,
+ ModelRace.Elezen => GenderRace.ElezenFemale,
+ ModelRace.Lalafell => GenderRace.LalafellFemale,
+ ModelRace.Miqote => GenderRace.MiqoteFemale,
+ ModelRace.Roegadyn => GenderRace.RoegadynFemale,
+ ModelRace.AuRa => GenderRace.AuRaFemale,
+ ModelRace.Viera => GenderRace.VieraFemale,
+ _ => GenderRace.Unknown,
+ },
+ Gender.FemaleNpc => modelRace switch
+ {
+ ModelRace.Midlander => GenderRace.MidlanderFemaleNpc,
+ ModelRace.Highlander => GenderRace.HighlanderFemaleNpc,
+ ModelRace.Elezen => GenderRace.ElezenFemaleNpc,
+ ModelRace.Lalafell => GenderRace.LalafellFemaleNpc,
+ ModelRace.Miqote => GenderRace.MiqoteFemaleNpc,
+ ModelRace.Roegadyn => GenderRace.RoegadynFemaleNpc,
+ ModelRace.AuRa => GenderRace.AuRaFemaleNpc,
+ ModelRace.Viera => GenderRace.VieraFemaleNpc,
+ _ => GenderRace.Unknown,
+ },
+ _ => GenderRace.Unknown,
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/RedrawType.cs b/Penumbra.GameData/Enums/RedrawType.cs
new file mode 100644
index 00000000..c3668504
--- /dev/null
+++ b/Penumbra.GameData/Enums/RedrawType.cs
@@ -0,0 +1,14 @@
+namespace Penumbra.GameData.Enums
+{
+ public enum RedrawType
+ {
+ WithoutSettings,
+ WithSettings,
+ OnlyWithSettings,
+ Unload,
+ RedrawWithoutSettings,
+ RedrawWithSettings,
+ AfterGPoseWithSettings,
+ AfterGPoseWithoutSettings,
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Enums/RspAttribute.cs b/Penumbra.GameData/Enums/RspAttribute.cs
new file mode 100644
index 00000000..07d03b67
--- /dev/null
+++ b/Penumbra.GameData/Enums/RspAttribute.cs
@@ -0,0 +1,92 @@
+using System.ComponentModel;
+
+namespace Penumbra.GameData.Enums
+{
+ public enum RspAttribute : byte
+ {
+ MaleMinSize,
+ MaleMaxSize,
+ MaleMinTail,
+ MaleMaxTail,
+ FemaleMinSize,
+ FemaleMaxSize,
+ FemaleMinTail,
+ FemaleMaxTail,
+ BustMinX,
+ BustMinY,
+ BustMinZ,
+ BustMaxX,
+ BustMaxY,
+ BustMaxZ,
+ NumAttributes,
+ }
+
+ public static class RspAttributeExtensions
+ {
+ public static Gender ToGender( this RspAttribute attribute )
+ {
+ return attribute switch
+ {
+ RspAttribute.MaleMinSize => Gender.Male,
+ RspAttribute.MaleMaxSize => Gender.Male,
+ RspAttribute.MaleMinTail => Gender.Male,
+ RspAttribute.MaleMaxTail => Gender.Male,
+ RspAttribute.FemaleMinSize => Gender.Female,
+ RspAttribute.FemaleMaxSize => Gender.Female,
+ RspAttribute.FemaleMinTail => Gender.Female,
+ RspAttribute.FemaleMaxTail => Gender.Female,
+ RspAttribute.BustMinX => Gender.Female,
+ RspAttribute.BustMinY => Gender.Female,
+ RspAttribute.BustMinZ => Gender.Female,
+ RspAttribute.BustMaxX => Gender.Female,
+ RspAttribute.BustMaxY => Gender.Female,
+ RspAttribute.BustMaxZ => Gender.Female,
+ _ => Gender.Unknown,
+ };
+ }
+
+ public static string ToUngenderedString( this RspAttribute attribute )
+ {
+ return attribute switch
+ {
+ RspAttribute.MaleMinSize => "MinSize",
+ RspAttribute.MaleMaxSize => "MaxSize",
+ RspAttribute.MaleMinTail => "MinTail",
+ RspAttribute.MaleMaxTail => "MaxTail",
+ RspAttribute.FemaleMinSize => "MinSize",
+ RspAttribute.FemaleMaxSize => "MaxSize",
+ RspAttribute.FemaleMinTail => "MinTail",
+ RspAttribute.FemaleMaxTail => "MaxTail",
+ RspAttribute.BustMinX => "BustMinX",
+ RspAttribute.BustMinY => "BustMinY",
+ RspAttribute.BustMinZ => "BustMinZ",
+ RspAttribute.BustMaxX => "BustMaxX",
+ RspAttribute.BustMaxY => "BustMaxY",
+ RspAttribute.BustMaxZ => "BustMaxZ",
+ _ => "",
+ };
+ }
+
+ public static string ToFullString( this RspAttribute attribute )
+ {
+ return attribute switch
+ {
+ RspAttribute.MaleMinSize => "Male Minimum Size",
+ RspAttribute.MaleMaxSize => "Male Maximum Size",
+ RspAttribute.FemaleMinSize => "Female Minimum Size",
+ RspAttribute.FemaleMaxSize => "Female Maximum Size",
+ RspAttribute.BustMinX => "Bust Minimum X-Axis",
+ RspAttribute.BustMaxX => "Bust Maximum X-Axis",
+ RspAttribute.BustMinY => "Bust Minimum Y-Axis",
+ RspAttribute.BustMaxY => "Bust Maximum Y-Axis",
+ RspAttribute.BustMinZ => "Bust Minimum Z-Axis",
+ RspAttribute.BustMaxZ => "Bust Maximum Z-Axis",
+ RspAttribute.MaleMinTail => "Male Minimum Tail Length",
+ RspAttribute.MaleMaxTail => "Male Maximum Tail Length",
+ RspAttribute.FemaleMinTail => "Female Minimum Tail Length",
+ RspAttribute.FemaleMaxTail => "Female Maximum Tail Length",
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/GameData.cs b/Penumbra.GameData/GameData.cs
new file mode 100644
index 00000000..cb294ca4
--- /dev/null
+++ b/Penumbra.GameData/GameData.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using Dalamud;
+using Dalamud.Data;
+using Lumina.Excel.GeneratedSheets;
+using Penumbra.GameData.Enums;
+using Penumbra.GameData.Structs;
+using Penumbra.GameData.Util;
+
+namespace Penumbra.GameData
+{
+ public static class GameData
+ {
+ internal static ObjectIdentification? Identification;
+ internal static readonly GamePathParser GamePathParser = new();
+
+ public static IObjectIdentifier GetIdentifier( DataManager dataManager, ClientLanguage clientLanguage )
+ {
+ Identification ??= new ObjectIdentification( dataManager, clientLanguage );
+ return Identification;
+ }
+
+ public static IObjectIdentifier GetIdentifier()
+ {
+ if( Identification == null )
+ {
+ throw new Exception( "Object Identification was not initialized." );
+ }
+
+ return Identification;
+ }
+
+ public static IGamePathParser GetGamePathParser()
+ => GamePathParser;
+ }
+
+ public interface IObjectIdentifier
+ {
+ public void Identify( IDictionary< string, object? > set, GamePath path );
+
+ public Dictionary< string, object? > Identify( GamePath path );
+ public Item? Identify( SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot );
+ }
+
+ public interface IGamePathParser
+ {
+ public ObjectType PathToObjectType( GamePath path );
+ public GameObjectInfo GetFileInfo( GamePath path );
+ public string VfxToKey( GamePath path );
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/GamePathParser.cs b/Penumbra.GameData/GamePathParser.cs
new file mode 100644
index 00000000..8afa3d1b
--- /dev/null
+++ b/Penumbra.GameData/GamePathParser.cs
@@ -0,0 +1,332 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+using Dalamud.Logging;
+using Penumbra.GameData.Enums;
+using Penumbra.GameData.Structs;
+using Penumbra.GameData.Util;
+
+namespace Penumbra.GameData
+{
+ internal class GamePathParser : IGamePathParser
+ {
+ private const string CharacterFolder = "chara";
+ private const string EquipmentFolder = "equipment";
+ private const string PlayerFolder = "human";
+ private const string WeaponFolder = "weapon";
+ private const string AccessoryFolder = "accessory";
+ private const string DemiHumanFolder = "demihuman";
+ private const string MonsterFolder = "monster";
+ private const string CommonFolder = "common";
+ private const string UiFolder = "ui";
+ private const string IconFolder = "icon";
+ private const string LoadingFolder = "loadingimage";
+ private const string MapFolder = "map";
+ private const string InterfaceFolder = "uld";
+ private const string FontFolder = "font";
+ private const string HousingFolder = "hou";
+ private const string VfxFolder = "vfx";
+ private const string WorldFolder1 = "bgcommon";
+ private const string WorldFolder2 = "bg";
+
+ // @formatter:off
+ private readonly Dictionary> _regexes = new()
+ { { FileType.Font, new Dictionary< ObjectType, Regex[] >(){ { ObjectType.Font, new Regex[]{ new(@"common/font/(?'fontname'.*)_(?'id'\d\d)(_lobby)?\.fdt") } } } }
+ , { FileType.Texture, new Dictionary< ObjectType, Regex[] >()
+ { { ObjectType.Icon, new Regex[]{ new(@"ui/icon/(?'group'\d*)(/(?'lang'[a-z]{2}))?(/(?'hq'hq))?/(?'id'\d*)\.tex") } }
+ , { ObjectType.Map, new Regex[]{ new(@"ui/map/(?'id'[a-z0-9]{4})/(?'variant'\d{2})/\k'id'\k'variant'(?'suffix'[a-z])?(_[a-z])?\.tex") } }
+ , { ObjectType.Weapon, new Regex[]{ new(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/texture/v(?'variant'\d{2})_w\k'id'b\k'weapon'(_[a-z])?_[a-z]\.tex") } }
+ , { ObjectType.Monster, new Regex[]{ new(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/texture/v(?'variant'\d{2})_m\k'monster'b\k'id'(_[a-z])?_[a-z]\.tex") } }
+ , { ObjectType.Equipment, new Regex[]{ new(@"chara/equipment/e(?'id'\d{4})/texture/v(?'variant'\d{2})_c(?'race'\d{4})e\k'id'_(?'slot'[a-z]{3})(_[a-z])?_[a-z]\.tex") } }
+ , { ObjectType.DemiHuman, new Regex[]{ new(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/texture/v(?'variant'\d{2})_d\k'id'e\k'equip'_(?'slot'[a-z]{3})(_[a-z])?_[a-z]\.tex") } }
+ , { ObjectType.Accessory, new Regex[]{ new(@"chara/accessory/a(?'id'\d{4})/texture/v(?'variant'\d{2})_c(?'race'\d{4})a\k'id'_(?'slot'[a-z]{3})_[a-z]\.tex") } }
+ , { ObjectType.Character, new Regex[]{ new(@"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/texture/(?'minus'(--)?)(v(?'variant'\d{2})_)?c\k'race'\k'typeabr'\k'id'(_(?'slot'[a-z]{3}))?(_[a-z])?_[a-z]\.tex")
+ , new(@"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/texture")
+ , new(@"chara/common/texture/skin(?'skin'.*)\.tex")
+ , new(@"chara/common/texture/decal_(?'location'[a-z]+)/[-_]?decal_(?'id'\d+).tex") } } } }
+ , { FileType.Model, new Dictionary< ObjectType, Regex[] >()
+ { { ObjectType.Weapon, new Regex[]{ new(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/model/w\k'id'b\k'weapon'\.mdl") } }
+ , { ObjectType.Monster, new Regex[]{ new(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/model/m\k'monster'b\k'id'\.mdl") } }
+ , { ObjectType.Equipment, new Regex[]{ new(@"chara/equipment/e(?'id'\d{4})/model/c(?'race'\d{4})e\k'id'_(?'slot'[a-z]{3})\.mdl") } }
+ , { ObjectType.DemiHuman, new Regex[]{ new(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/model/d\k'id'e\k'equip'_(?'slot'[a-z]{3})\.mdl") } }
+ , { ObjectType.Accessory, new Regex[]{ new(@"chara/accessory/a(?'id'\d{4})/model/c(?'race'\d{4})a\k'id'_(?'slot'[a-z]{3})\.mdl") } }
+ , { ObjectType.Character, new Regex[]{ new(@"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/model/c\k'race'\k'typeabr'\k'id'_(?'slot'[a-z]{3})\.mdl") } } } }
+ , { FileType.Material, new Dictionary< ObjectType, Regex[] >()
+ { { ObjectType.Weapon, new Regex[]{ new(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/material/v(?'variant'\d{4})/mt_w\k'id'b\k'weapon'_[a-z]\.mtrl") } }
+ , { ObjectType.Monster, new Regex[]{ new(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/material/v(?'variant'\d{4})/mt_m\k'monster'b\k'id'_[a-z]\.mtrl") } }
+ , { ObjectType.Equipment, new Regex[]{ new(@"chara/equipment/e(?'id'\d{4})/material/v(?'variant'\d{4})/mt_c(?'race'\d{4})e\k'id'_(?'slot'[a-z]{3})_[a-z]\.mtrl") } }
+ , { ObjectType.DemiHuman, new Regex[]{ new(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/material/v(?'variant'\d{4})/mt_d\k'id'e\k'equip'_(?'slot'[a-z]{3})_[a-z]\.mtrl") } }
+ , { ObjectType.Accessory, new Regex[]{ new(@"chara/accessory/a(?'id'\d{4})/material/v(?'variant'\d{4})/mt_c(?'race'\d{4})a\k'id'_(?'slot'[a-z]{3})_[a-z]\.mtrl") } }
+ , { ObjectType.Character, new Regex[]{ new(@"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/material/v(?'variant'\d{4})/mt_c\k'race'\k'typeabr'\k'id'(_(?'slot'[a-z]{3}))?_[a-z]\.mtrl") } } } }
+ , { FileType.Imc, new Dictionary< ObjectType, Regex[] >()
+ { { ObjectType.Weapon, new Regex[]{ new(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/b\k'weapon'\.imc") } }
+ , { ObjectType.Monster, new Regex[]{ new(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/b\k'id'\.imc") } }
+ , { ObjectType.Equipment, new Regex[]{ new(@"chara/equipment/e(?'id'\d{4})/e\k'id'\.imc") } }
+ , { ObjectType.DemiHuman, new Regex[]{ new(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/e\k'equip'\.imc") } }
+ , { ObjectType.Accessory, new Regex[]{ new(@"chara/accessory/a(?'id'\d{4})/a\k'id'\.imc") } } } },
+ };
+ // @formatter:on
+
+ public ObjectType PathToObjectType( GamePath path )
+ {
+ if( path.Empty )
+ {
+ return ObjectType.Unknown;
+ }
+
+ string p = path;
+ var folders = p.Split( '/' );
+ if( folders.Length < 2 )
+ {
+ return ObjectType.Unknown;
+ }
+
+ return folders[ 0 ] switch
+ {
+ CharacterFolder => folders[ 1 ] switch
+ {
+ EquipmentFolder => ObjectType.Equipment,
+ AccessoryFolder => ObjectType.Accessory,
+ WeaponFolder => ObjectType.Weapon,
+ PlayerFolder => ObjectType.Character,
+ DemiHumanFolder => ObjectType.DemiHuman,
+ MonsterFolder => ObjectType.Monster,
+ CommonFolder => ObjectType.Character,
+ _ => ObjectType.Unknown,
+ },
+ UiFolder => folders[ 1 ] switch
+ {
+ IconFolder => ObjectType.Icon,
+ LoadingFolder => ObjectType.LoadingScreen,
+ MapFolder => ObjectType.Map,
+ InterfaceFolder => ObjectType.Interface,
+ _ => ObjectType.Unknown,
+ },
+ CommonFolder => folders[ 1 ] switch
+ {
+ FontFolder => ObjectType.Font,
+ _ => ObjectType.Unknown,
+ },
+ HousingFolder => ObjectType.Housing,
+ WorldFolder1 => folders[ 1 ] switch
+ {
+ HousingFolder => ObjectType.Housing,
+ _ => ObjectType.World,
+ },
+ WorldFolder2 => ObjectType.World,
+ VfxFolder => ObjectType.Vfx,
+ _ => ObjectType.Unknown,
+ };
+ }
+
+ private (FileType, ObjectType, Match?) ParseGamePath( GamePath path )
+ {
+ if( !Names.ExtensionToFileType.TryGetValue( Extension( path ), out var fileType ) )
+ {
+ fileType = FileType.Unknown;
+ }
+
+ var objectType = PathToObjectType( path );
+
+ if( !_regexes.TryGetValue( fileType, out var objectDict ) )
+ {
+ return ( fileType, objectType, null );
+ }
+
+ if( !objectDict.TryGetValue( objectType, out var regexes ) )
+ {
+ return ( fileType, objectType, null );
+ }
+
+ foreach( var regex in regexes )
+ {
+ var match = regex.Match( path );
+ if( match.Success )
+ {
+ return ( fileType, objectType, match );
+ }
+ }
+
+ return ( fileType, objectType, null );
+ }
+
+ private static string Extension( string filename )
+ {
+ var extIdx = filename.LastIndexOf( '.' );
+ return extIdx < 0 ? "" : filename.Substring( extIdx );
+ }
+
+ private static GameObjectInfo HandleEquipment( FileType fileType, GroupCollection groups )
+ {
+ var setId = ushort.Parse( groups[ "id" ].Value );
+ if( fileType == FileType.Imc )
+ {
+ return GameObjectInfo.Equipment( fileType, setId );
+ }
+
+ var gr = Names.GenderRaceFromCode( groups[ "race" ].Value );
+ var slot = Names.SuffixToEquipSlot[ groups[ "slot" ].Value ];
+ if( fileType == FileType.Model )
+ {
+ return GameObjectInfo.Equipment( fileType, setId, gr, slot );
+ }
+
+ var variant = byte.Parse( groups[ "variant" ].Value );
+ return GameObjectInfo.Equipment( fileType, setId, gr, slot, variant );
+ }
+
+ private static GameObjectInfo HandleWeapon( FileType fileType, GroupCollection groups )
+ {
+ var weaponId = ushort.Parse( groups[ "weapon" ].Value );
+ var setId = ushort.Parse( groups[ "id" ].Value );
+ if( fileType == FileType.Imc || fileType == FileType.Model )
+ {
+ return GameObjectInfo.Weapon( fileType, setId, weaponId );
+ }
+
+ var variant = byte.Parse( groups[ "variant" ].Value );
+ return GameObjectInfo.Weapon( fileType, setId, weaponId, variant );
+ }
+
+ private static GameObjectInfo HandleMonster( FileType fileType, GroupCollection groups )
+ {
+ var monsterId = ushort.Parse( groups[ "monster" ].Value );
+ var bodyId = ushort.Parse( groups[ "id" ].Value );
+ if( fileType == FileType.Imc || fileType == FileType.Model )
+ {
+ return GameObjectInfo.Monster( fileType, monsterId, bodyId );
+ }
+
+ var variant = byte.Parse( groups[ "variant" ].Value );
+ return GameObjectInfo.Monster( fileType, monsterId, bodyId, variant );
+ }
+
+ private static GameObjectInfo HandleDemiHuman( FileType fileType, GroupCollection groups )
+ {
+ var demiHumanId = ushort.Parse( groups[ "id" ].Value );
+ var equipId = ushort.Parse( groups[ "equip" ].Value );
+ if( fileType == FileType.Imc )
+ {
+ return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId );
+ }
+
+ var slot = Names.SuffixToEquipSlot[ groups[ "slot" ].Value ];
+ if( fileType == FileType.Model )
+ {
+ return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot );
+ }
+
+ var variant = byte.Parse( groups[ "variant" ].Value );
+ return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot, variant );
+ }
+
+ private static GameObjectInfo HandleCustomization( FileType fileType, GroupCollection groups )
+ {
+ if( groups[ "skin" ].Success )
+ {
+ return GameObjectInfo.Customization( fileType, CustomizationType.Skin );
+ }
+
+ var id = ushort.Parse( groups[ "id" ].Value );
+ if( groups[ "location" ].Success )
+ {
+ var tmpType = groups[ "location" ].Value == "face" ? CustomizationType.DecalFace
+ : groups[ "location" ].Value == "equip" ? CustomizationType.DecalEquip : CustomizationType.Unknown;
+ return GameObjectInfo.Customization( fileType, tmpType, id );
+ }
+
+ var gr = Names.GenderRaceFromCode( groups[ "race" ].Value );
+ var bodySlot = Names.StringToBodySlot[ groups[ "type" ].Value ];
+ var type = groups[ "slot" ].Success
+ ? Names.SuffixToCustomizationType[ groups[ "slot" ].Value ]
+ : CustomizationType.Skin;
+ if( fileType == FileType.Material )
+ {
+ var variant = byte.Parse( groups[ "variant" ].Value );
+ return GameObjectInfo.Customization( fileType, type, id, gr, bodySlot, variant );
+ }
+
+ return GameObjectInfo.Customization( fileType, type, id, gr, bodySlot );
+ }
+
+ private static GameObjectInfo HandleIcon( FileType fileType, GroupCollection groups )
+ {
+ var hq = groups[ "hq" ].Success;
+ var id = uint.Parse( groups[ "id" ].Value );
+ if( !groups[ "lang" ].Success )
+ {
+ return GameObjectInfo.Icon( fileType, id, hq );
+ }
+
+ var language = groups[ "lang" ].Value switch
+ {
+ "en" => Dalamud.ClientLanguage.English,
+ "ja" => Dalamud.ClientLanguage.Japanese,
+ "de" => Dalamud.ClientLanguage.German,
+ "fr" => Dalamud.ClientLanguage.French,
+ _ => Dalamud.ClientLanguage.English,
+ };
+ return GameObjectInfo.Icon( fileType, id, hq, language );
+ }
+
+ private static GameObjectInfo HandleMap( FileType fileType, GroupCollection groups )
+ {
+ var map = Encoding.ASCII.GetBytes( groups[ "id" ].Value );
+ var variant = byte.Parse( groups[ "variant" ].Value );
+ if( groups[ "suffix" ].Success )
+ {
+ var suffix = Encoding.ASCII.GetBytes( groups[ "suffix" ].Value )[ 0 ];
+ return GameObjectInfo.Map( fileType, map[ 0 ], map[ 1 ], map[ 2 ], map[ 3 ], variant, suffix );
+ }
+
+ return GameObjectInfo.Map( fileType, map[ 0 ], map[ 1 ], map[ 2 ], map[ 3 ], variant );
+ }
+
+ public GameObjectInfo GetFileInfo( GamePath path )
+ {
+ var (fileType, objectType, match) = ParseGamePath( path );
+ if( match == null || !match.Success )
+ {
+ return new GameObjectInfo { FileType = fileType, ObjectType = objectType };
+ }
+
+ try
+ {
+ var groups = match.Groups;
+ switch( objectType )
+ {
+ case ObjectType.Accessory: return HandleEquipment( fileType, groups );
+ case ObjectType.Equipment: return HandleEquipment( fileType, groups );
+ case ObjectType.Weapon: return HandleWeapon( fileType, groups );
+ case ObjectType.Map: return HandleMap( fileType, groups );
+ case ObjectType.Monster: return HandleMonster( fileType, groups );
+ case ObjectType.DemiHuman: return HandleDemiHuman( fileType, groups );
+ case ObjectType.Character: return HandleCustomization( fileType, groups );
+ case ObjectType.Icon: return HandleIcon( fileType, groups );
+ }
+ }
+ catch( Exception e )
+ {
+ PluginLog.Error( $"Could not parse {path}:\n{e}" );
+ }
+
+ return new GameObjectInfo { FileType = fileType, ObjectType = objectType };
+ }
+
+ private readonly Regex _vfxRegexTmb = new( @"chara/action/(?'key'[^\s]+?)\.tmb" );
+ private readonly Regex _vfxRegexPap = new( @"chara/human/c0101/animation/a0001/[^\s]+?/(?'key'[^\s]+?)\.pap" );
+
+ public string VfxToKey( GamePath path )
+ {
+ var match = _vfxRegexTmb.Match( path );
+ if( match.Success )
+ {
+ return match.Groups[ "key" ].Value.ToLowerInvariant();
+ }
+
+ match = _vfxRegexPap.Match( path );
+ return match.Success ? match.Groups[ "key" ].Value.ToLowerInvariant() : string.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/ObjectIdentification.cs b/Penumbra.GameData/ObjectIdentification.cs
new file mode 100644
index 00000000..93e69b1d
--- /dev/null
+++ b/Penumbra.GameData/ObjectIdentification.cs
@@ -0,0 +1,325 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using Dalamud;
+using Dalamud.Data;
+using Lumina.Excel.GeneratedSheets;
+using Penumbra.GameData.Enums;
+using Penumbra.GameData.Structs;
+using Penumbra.GameData.Util;
+using Action = Lumina.Excel.GeneratedSheets.Action;
+
+namespace Penumbra.GameData
+{
+ internal class ObjectIdentification : IObjectIdentifier
+ {
+ public static DataManager? DataManager = null!;
+ private readonly List< (ulong, HashSet< Item >) > _weapons;
+ private readonly List< (ulong, HashSet< Item >) > _equipment;
+ private readonly Dictionary< string, HashSet< Action > > _actions;
+
+ private static bool Add( IDictionary< ulong, HashSet< Item > > dict, ulong key, Item item )
+ {
+ if( dict.TryGetValue( key, out var list ) )
+ {
+ return list.Add( item );
+ }
+
+ dict[ key ] = new HashSet< Item > { item };
+ return true;
+ }
+
+ private static ulong EquipmentKey( Item i )
+ {
+ var model = ( ulong )( ( Lumina.Data.Parsing.Quad )i.ModelMain ).A;
+ var variant = ( ulong )( ( Lumina.Data.Parsing.Quad )i.ModelMain ).B;
+ var slot = ( ulong )( ( EquipSlot )i.EquipSlotCategory.Row ).ToSlot();
+ return ( model << 32 ) | ( slot << 16 ) | variant;
+ }
+
+ private static ulong WeaponKey( Item i, bool offhand )
+ {
+ var quad = offhand ? ( Lumina.Data.Parsing.Quad )i.ModelSub : ( Lumina.Data.Parsing.Quad )i.ModelMain;
+ var model = ( ulong )quad.A;
+ var type = ( ulong )quad.B;
+ var variant = ( ulong )quad.C;
+
+ return ( model << 32 ) | ( type << 16 ) | variant;
+ }
+
+ private void AddAction( string key, Action action )
+ {
+ if( key.Length == 0 )
+ {
+ return;
+ }
+
+ key = key.ToLowerInvariant();
+ if( _actions.TryGetValue( key, out var actions ) )
+ {
+ actions.Add( action );
+ }
+ else
+ {
+ _actions[ key ] = new HashSet< Action > { action };
+ }
+ }
+
+ public ObjectIdentification( DataManager dataManager, ClientLanguage clientLanguage )
+ {
+ DataManager = dataManager;
+ var items = dataManager.GetExcelSheet< Item >( clientLanguage )!;
+ SortedList< ulong, HashSet< Item > > weapons = new();
+ SortedList< ulong, HashSet< Item > > equipment = new();
+ foreach( var item in items )
+ {
+ switch( ( EquipSlot )item.EquipSlotCategory.Row )
+ {
+ case EquipSlot.MainHand:
+ case EquipSlot.OffHand:
+ case EquipSlot.BothHand:
+ if( item.ModelMain != 0 )
+ {
+ Add( weapons, WeaponKey( item, false ), item );
+ }
+
+ if( item.ModelSub != 0 )
+ {
+ Add( weapons, WeaponKey( item, true ), item );
+ }
+
+ break;
+ // Accessories
+ case EquipSlot.RFinger:
+ case EquipSlot.Wrists:
+ case EquipSlot.Ears:
+ case EquipSlot.Neck:
+ Add( equipment, EquipmentKey( item ), item );
+ break;
+ // Equipment
+ case EquipSlot.Head:
+ case EquipSlot.Body:
+ case EquipSlot.Hands:
+ case EquipSlot.Legs:
+ case EquipSlot.Feet:
+ case EquipSlot.BodyHands:
+ case EquipSlot.BodyHandsLegsFeet:
+ case EquipSlot.BodyLegsFeet:
+ case EquipSlot.FullBody:
+ case EquipSlot.HeadBody:
+ case EquipSlot.LegsFeet:
+ Add( equipment, EquipmentKey( item ), item );
+ break;
+ default: continue;
+ }
+ }
+
+ _actions = new Dictionary< string, HashSet< Action > >();
+ foreach( var action in dataManager.GetExcelSheet< Action >( clientLanguage )!
+ .Where( a => a.Name.ToString().Any() ) )
+ {
+ var startKey = action.AnimationStart?.Value?.Name?.Value?.Key.ToString() ?? string.Empty;
+ var endKey = action.AnimationEnd?.Value?.Key.ToString() ?? string.Empty;
+ var hitKey = action.ActionTimelineHit?.Value?.Key.ToString() ?? string.Empty;
+ AddAction( startKey, action );
+ AddAction( endKey, action );
+ AddAction( hitKey, action );
+ }
+
+ _weapons = weapons.Select( kvp => ( kvp.Key, kvp.Value ) ).ToList();
+ _equipment = equipment.Select( kvp => ( kvp.Key, kvp.Value ) ).ToList();
+ }
+
+ private class Comparer : IComparer< (ulong, HashSet< Item >) >
+ {
+ public int Compare( (ulong, HashSet< Item >) x, (ulong, HashSet< Item >) y )
+ => x.Item1.CompareTo( y.Item1 );
+ }
+
+ private static (int, int) FindIndexRange( List< (ulong, HashSet< Item >) > list, ulong key, ulong mask )
+ {
+ var maskedKey = key & mask;
+ var idx = list.BinarySearch( 0, list.Count, ( key, null! ), new Comparer() );
+ if( idx < 0 )
+ {
+ if( ~idx == list.Count || maskedKey != ( list[ ~idx ].Item1 & mask ) )
+ {
+ return ( -1, -1 );
+ }
+
+ idx = ~idx;
+ }
+
+ var endIdx = idx + 1;
+ while( endIdx < list.Count && maskedKey == ( list[ endIdx ].Item1 & mask ) )
+ {
+ ++endIdx;
+ }
+
+ return ( idx, endIdx );
+ }
+
+ private void FindEquipment( IDictionary< string, object? > set, GameObjectInfo info )
+ {
+ var key = ( ulong )info.PrimaryId << 32;
+ var mask = 0xFFFF00000000ul;
+ if( info.EquipSlot != EquipSlot.Unknown )
+ {
+ key |= ( ulong )info.EquipSlot.ToSlot() << 16;
+ mask |= 0xFFFF0000;
+ }
+
+ if( info.Variant != 0 )
+ {
+ key |= info.Variant;
+ mask |= 0xFFFF;
+ }
+
+ var (start, end) = FindIndexRange( _equipment, key, mask );
+ if( start == -1 )
+ {
+ return;
+ }
+
+ for( ; start < end; ++start )
+ {
+ foreach( var item in _equipment[ start ].Item2 )
+ {
+ set[ item.Name.ToString() ] = item;
+ }
+ }
+ }
+
+ private void FindWeapon( IDictionary< string, object? > set, GameObjectInfo info )
+ {
+ var key = ( ulong )info.PrimaryId << 32;
+ var mask = 0xFFFF00000000ul;
+ if( info.SecondaryId != 0 )
+ {
+ key |= ( ulong )info.SecondaryId << 16;
+ mask |= 0xFFFF0000;
+ }
+
+ if( info.Variant != 0 )
+ {
+ key |= info.Variant;
+ mask |= 0xFFFF;
+ }
+
+ var (start, end) = FindIndexRange( _weapons, key, mask );
+ if( start == -1 )
+ {
+ return;
+ }
+
+ for( ; start < end; ++start )
+ {
+ foreach( var item in _weapons[ start ].Item2 )
+ {
+ set[ item.Name.ToString() ] = item;
+ }
+ }
+ }
+
+
+ private void IdentifyParsed( IDictionary< string, object? > set, GameObjectInfo info )
+ {
+ switch( info.ObjectType )
+ {
+ case ObjectType.Unknown:
+ case ObjectType.LoadingScreen:
+ case ObjectType.Map:
+ case ObjectType.Interface:
+ case ObjectType.Vfx:
+ case ObjectType.World:
+ case ObjectType.Housing:
+ case ObjectType.DemiHuman:
+ case ObjectType.Monster:
+ case ObjectType.Icon:
+ case ObjectType.Font:
+ // Don't do anything for these cases.
+ break;
+ case ObjectType.Accessory:
+ case ObjectType.Equipment:
+ FindEquipment( set, info );
+ break;
+ case ObjectType.Weapon:
+ FindWeapon( set, info );
+ break;
+ case ObjectType.Character:
+ var (gender, race) = info.GenderRace.Split();
+ var raceString = race != ModelRace.Unknown ? race.ToName() + " " : "";
+ var genderString = gender != Gender.Unknown ? gender.ToName() + " " : "Player ";
+ if( info.CustomizationType == CustomizationType.Skin )
+ {
+ set[ $"Customization: {raceString}{genderString}Skin Textures" ] = null;
+ }
+ else
+ {
+ var customizationString =
+ $"Customization: {race} {gender} {info.BodySlot} ({info.CustomizationType}) {info.PrimaryId}";
+ set[ customizationString ] = null;
+ }
+
+ break;
+
+ default: throw new InvalidEnumArgumentException();
+ }
+ }
+
+ private void IdentifyVfx( IDictionary< string, object? > set, GamePath path )
+ {
+ var key = GameData.GamePathParser.VfxToKey( path );
+ if( key.Length == 0 || !_actions.TryGetValue( key, out var actions ) )
+ {
+ return;
+ }
+
+ foreach( var action in actions )
+ {
+ set[ $"Action: {action.Name}" ] = action;
+ }
+ }
+
+ public void Identify( IDictionary< string, object? > set, GamePath path )
+ {
+ if( ( ( string )path ).EndsWith( ".pap" ) || ( ( string )path ).EndsWith( ".tmb" ) )
+ {
+ IdentifyVfx( set, path );
+ }
+ else
+ {
+ var info = GameData.GamePathParser.GetFileInfo( path );
+ IdentifyParsed( set, info );
+ }
+ }
+
+ public Dictionary< string, object? > Identify( GamePath path )
+ {
+ Dictionary< string, object? > ret = new();
+ Identify( ret, path );
+ return ret;
+ }
+
+ public Item? Identify( SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot )
+ {
+ switch( slot )
+ {
+ case EquipSlot.MainHand:
+ case EquipSlot.OffHand:
+ {
+ var (begin, _) = FindIndexRange( _weapons, ( ( ulong )setId << 32 ) | ( ( ulong )weaponType << 16 ) | variant,
+ 0xFFFFFFFFFFFF );
+ return begin >= 0 ? _weapons[ begin ].Item2.FirstOrDefault() : null;
+ }
+ default:
+ {
+ var (begin, _) = FindIndexRange( _equipment,
+ ( ( ulong )setId << 32 ) | ( ( ulong )slot.ToSlot() << 16 ) | variant,
+ 0xFFFFFFFFFFFF );
+ return begin >= 0 ? _equipment[ begin ].Item2.FirstOrDefault() : null;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Penumbra.GameData.csproj b/Penumbra.GameData/Penumbra.GameData.csproj
new file mode 100644
index 00000000..c7dbc908
--- /dev/null
+++ b/Penumbra.GameData/Penumbra.GameData.csproj
@@ -0,0 +1,48 @@
+
+
+ net5.0-windows
+ preview
+ x64
+ Penumbra.GameData
+ absolute gangstas
+ Penumbra
+ Copyright © 2020
+ 1.0.0.0
+ 1.0.0.0
+ bin\$(Configuration)\
+ true
+ enable
+
+
+
+ full
+ DEBUG;TRACE
+
+
+
+ pdbonly
+
+
+
+ $(MSBuildWarningsAsMessages);MSB3277
+
+
+
+
+ $(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll
+ False
+
+
+ $(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll
+ False
+
+
+ $(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll
+ False
+
+
+
+
+
+
+
diff --git a/Penumbra.GameData/Structs/CharacterArmor.cs b/Penumbra.GameData/Structs/CharacterArmor.cs
new file mode 100644
index 00000000..c61ac7ab
--- /dev/null
+++ b/Penumbra.GameData/Structs/CharacterArmor.cs
@@ -0,0 +1,15 @@
+using System.Runtime.InteropServices;
+
+namespace Penumbra.GameData.Structs
+{
+ [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+ public readonly struct CharacterArmor
+ {
+ public readonly SetId Set;
+ public readonly byte Variant;
+ public readonly StainId Stain;
+
+ public override string ToString()
+ => $"{Set},{Variant},{Stain}";
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/CharacterEquipment.cs b/Penumbra.GameData/Structs/CharacterEquipment.cs
new file mode 100644
index 00000000..84d244ae
--- /dev/null
+++ b/Penumbra.GameData/Structs/CharacterEquipment.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Runtime.InteropServices;
+using Dalamud.Game.ClientState.Objects.Types;
+
+// Read the customization data regarding weapons and displayable equipment from an actor struct.
+// Stores the data in a 56 bytes, i.e. 7 longs for easier comparison.
+namespace Penumbra.GameData.Structs
+{
+ [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+ public class CharacterEquipment
+ {
+ public const int MainWeaponOffset = 0x0F08;
+ public const int OffWeaponOffset = 0x0F70;
+ public const int EquipmentOffset = 0x1040;
+ public const int EquipmentSlots = 10;
+ public const int WeaponSlots = 2;
+
+ public CharacterWeapon MainHand;
+ public CharacterWeapon OffHand;
+ public CharacterArmor Head;
+ public CharacterArmor Body;
+ public CharacterArmor Hands;
+ public CharacterArmor Legs;
+ public CharacterArmor Feet;
+ public CharacterArmor Ears;
+ public CharacterArmor Neck;
+ public CharacterArmor Wrists;
+ public CharacterArmor RFinger;
+ public CharacterArmor LFinger;
+ public ushort IsSet; // Also fills struct size to 56, a multiple of 8.
+
+ public CharacterEquipment()
+ => Clear();
+
+ public CharacterEquipment( Character actor )
+ : this( actor.Address )
+ { }
+
+ public override string ToString()
+ => IsSet == 0
+ ? "(Not Set)"
+ : $"({MainHand}) | ({OffHand}) | ({Head}) | ({Body}) | ({Hands}) | ({Legs}) | "
+ + $"({Feet}) | ({Ears}) | ({Neck}) | ({Wrists}) | ({LFinger}) | ({RFinger})";
+
+ public bool Equal( Character rhs )
+ => CompareData( new CharacterEquipment( rhs ) );
+
+ public bool Equal( CharacterEquipment rhs )
+ => CompareData( rhs );
+
+ public bool CompareAndUpdate( Character rhs )
+ => CompareAndOverwrite( new CharacterEquipment( rhs ) );
+
+ public bool CompareAndUpdate( CharacterEquipment rhs )
+ => CompareAndOverwrite( rhs );
+
+ private unsafe CharacterEquipment( IntPtr actorAddress )
+ {
+ IsSet = 1;
+ var actorPtr = ( byte* )actorAddress.ToPointer();
+ fixed( CharacterWeapon* main = &MainHand, off = &OffHand )
+ {
+ Buffer.MemoryCopy( actorPtr + MainWeaponOffset, main, sizeof( CharacterWeapon ), sizeof( CharacterWeapon ) );
+ Buffer.MemoryCopy( actorPtr + OffWeaponOffset, off, sizeof( CharacterWeapon ), sizeof( CharacterWeapon ) );
+ }
+
+ fixed( CharacterArmor* equipment = &Head )
+ {
+ Buffer.MemoryCopy( actorPtr + EquipmentOffset, equipment, EquipmentSlots * sizeof( CharacterArmor ),
+ EquipmentSlots * sizeof( CharacterArmor ) );
+ }
+ }
+
+ public unsafe void Clear()
+ {
+ fixed( CharacterWeapon* main = &MainHand )
+ {
+ var structSizeEights = ( 2 + EquipmentSlots * sizeof( CharacterArmor ) + WeaponSlots * sizeof( CharacterWeapon ) ) / 8;
+ for( ulong* ptr = ( ulong* )main, end = ptr + structSizeEights; ptr != end; ++ptr )
+ {
+ *ptr = 0;
+ }
+ }
+ }
+
+ private unsafe bool CompareAndOverwrite( CharacterEquipment rhs )
+ {
+ var structSizeEights = ( 2 + EquipmentSlots * sizeof( CharacterArmor ) + WeaponSlots * sizeof( CharacterWeapon ) ) / 8;
+ var ret = true;
+ fixed( CharacterWeapon* data1 = &MainHand, data2 = &rhs.MainHand )
+ {
+ var ptr1 = ( ulong* )data1;
+ var ptr2 = ( ulong* )data2;
+ for( var end = ptr1 + structSizeEights; ptr1 != end; ++ptr1, ++ptr2 )
+ {
+ if( *ptr1 != *ptr2 )
+ {
+ *ptr1 = *ptr2;
+ ret = false;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ private unsafe bool CompareData( CharacterEquipment rhs )
+ {
+ var structSizeEights = ( 2 + EquipmentSlots * sizeof( CharacterArmor ) + WeaponSlots * sizeof( CharacterWeapon ) ) / 8;
+ fixed( CharacterWeapon* data1 = &MainHand, data2 = &rhs.MainHand )
+ {
+ var ptr1 = ( ulong* )data1;
+ var ptr2 = ( ulong* )data2;
+ for( var end = ptr1 + structSizeEights; ptr1 != end; ++ptr1, ++ptr2 )
+ {
+ if( *ptr1 != *ptr2 )
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public unsafe void WriteBytes( byte[] array, int offset = 0 )
+ {
+ fixed( CharacterWeapon* data = &MainHand )
+ {
+ Marshal.Copy( new IntPtr( data ), array, offset, 56 );
+ }
+ }
+
+ public byte[] ToBytes()
+ {
+ var ret = new byte[56];
+ WriteBytes( ret );
+ return ret;
+ }
+
+ public unsafe void FromBytes( byte[] array, int offset = 0 )
+ {
+ fixed( CharacterWeapon* data = &MainHand )
+ {
+ Marshal.Copy( array, offset, new IntPtr( data ), 56 );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/CharacterWeapon.cs b/Penumbra.GameData/Structs/CharacterWeapon.cs
new file mode 100644
index 00000000..5a742073
--- /dev/null
+++ b/Penumbra.GameData/Structs/CharacterWeapon.cs
@@ -0,0 +1,16 @@
+using System.Runtime.InteropServices;
+
+namespace Penumbra.GameData.Structs
+{
+ [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+ public readonly struct CharacterWeapon
+ {
+ public readonly SetId Set;
+ public readonly WeaponType Type;
+ public readonly ushort Variant;
+ public readonly StainId Stain;
+
+ public override string ToString()
+ => $"{Set},{Type},{Variant},{Stain}";
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/EqdpEntry.cs b/Penumbra.GameData/Structs/EqdpEntry.cs
new file mode 100644
index 00000000..763809ae
--- /dev/null
+++ b/Penumbra.GameData/Structs/EqdpEntry.cs
@@ -0,0 +1,107 @@
+using System;
+using System.ComponentModel;
+using Penumbra.GameData.Enums;
+
+namespace Penumbra.GameData.Structs
+{
+ [Flags]
+ public enum EqdpEntry : ushort
+ {
+ Invalid = 0,
+ Head1 = 0b0000000001,
+ Head2 = 0b0000000010,
+ HeadMask = 0b0000000011,
+
+ Body1 = 0b0000000100,
+ Body2 = 0b0000001000,
+ BodyMask = 0b0000001100,
+
+ Hands1 = 0b0000010000,
+ Hands2 = 0b0000100000,
+ HandsMask = 0b0000110000,
+
+ Legs1 = 0b0001000000,
+ Legs2 = 0b0010000000,
+ LegsMask = 0b0011000000,
+
+ Feet1 = 0b0100000000,
+ Feet2 = 0b1000000000,
+ FeetMask = 0b1100000000,
+
+ Ears1 = 0b0000000001,
+ Ears2 = 0b0000000010,
+ EarsMask = 0b0000000011,
+
+ Neck1 = 0b0000000100,
+ Neck2 = 0b0000001000,
+ NeckMask = 0b0000001100,
+
+ Wrists1 = 0b0000010000,
+ Wrists2 = 0b0000100000,
+ WristsMask = 0b0000110000,
+
+ RingR1 = 0b0001000000,
+ RingR2 = 0b0010000000,
+ RingRMask = 0b0011000000,
+
+ RingL1 = 0b0100000000,
+ RingL2 = 0b1000000000,
+ RingLMask = 0b1100000000,
+ }
+
+ public static class Eqdp
+ {
+ public static int Offset( EquipSlot slot )
+ {
+ return slot switch
+ {
+ EquipSlot.Head => 0,
+ EquipSlot.Body => 2,
+ EquipSlot.Hands => 4,
+ EquipSlot.Legs => 6,
+ EquipSlot.Feet => 8,
+ EquipSlot.Ears => 0,
+ EquipSlot.Neck => 2,
+ EquipSlot.Wrists => 4,
+ EquipSlot.RFinger => 6,
+ EquipSlot.LFinger => 8,
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static EqdpEntry FromSlotAndBits( EquipSlot slot, bool bit1, bool bit2 )
+ {
+ EqdpEntry ret = 0;
+ var offset = Offset( slot );
+ if( bit1 )
+ {
+ ret |= ( EqdpEntry )( 1 << offset );
+ }
+
+ if( bit2 )
+ {
+ ret |= ( EqdpEntry )( 1 << ( offset + 1 ) );
+ }
+
+ return ret;
+ }
+
+ public static EqdpEntry Mask( EquipSlot slot )
+ {
+ return slot switch
+ {
+ EquipSlot.Head => EqdpEntry.HeadMask,
+ EquipSlot.Body => EqdpEntry.BodyMask,
+ EquipSlot.Hands => EqdpEntry.HandsMask,
+ EquipSlot.Legs => EqdpEntry.LegsMask,
+ EquipSlot.Feet => EqdpEntry.FeetMask,
+ EquipSlot.Ears => EqdpEntry.EarsMask,
+ EquipSlot.Neck => EqdpEntry.NeckMask,
+ EquipSlot.Wrists => EqdpEntry.WristsMask,
+ EquipSlot.RFinger => EqdpEntry.RingRMask,
+ EquipSlot.LFinger => EqdpEntry.RingLMask,
+ _ => 0,
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/EqpEntry.cs b/Penumbra.GameData/Structs/EqpEntry.cs
new file mode 100644
index 00000000..5b54baa8
--- /dev/null
+++ b/Penumbra.GameData/Structs/EqpEntry.cs
@@ -0,0 +1,308 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.ComponentModel;
+using Penumbra.GameData.Enums;
+
+namespace Penumbra.GameData.Structs
+{
+ [Flags]
+ public enum EqpEntry : ulong
+ {
+ BodyEnabled = 0x00_01ul,
+ BodyHideWaist = 0x00_02ul,
+ _2 = 0x00_04ul,
+ BodyHideGlovesS = 0x00_08ul,
+ _4 = 0x00_10ul,
+ BodyHideGlovesM = 0x00_20ul,
+ BodyHideGlovesL = 0x00_40ul,
+ BodyHideGorget = 0x00_80ul,
+ BodyShowLeg = 0x01_00ul,
+ BodyShowHand = 0x02_00ul,
+ BodyShowHead = 0x04_00ul,
+ BodyShowNecklace = 0x08_00ul,
+ BodyShowBracelet = 0x10_00ul,
+ BodyShowTail = 0x20_00ul,
+ DisableBreastPhysics = 0x40_00ul,
+ _15 = 0x80_00ul,
+ BodyMask = 0xFF_FFul,
+
+ LegsEnabled = 0x01ul << 16,
+ LegsHideKneePads = 0x02ul << 16,
+ LegsHideBootsS = 0x04ul << 16,
+ LegsHideBootsM = 0x08ul << 16,
+ _20 = 0x10ul << 16,
+ LegsShowFoot = 0x20ul << 16,
+ LegsShowTail = 0x40ul << 16,
+ _23 = 0x80ul << 16,
+ LegsMask = 0xFFul << 16,
+
+ HandsEnabled = 0x01ul << 24,
+ HandsHideElbow = 0x02ul << 24,
+ HandsHideForearm = 0x04ul << 24,
+ _27 = 0x08ul << 24,
+ HandShowBracelet = 0x10ul << 24,
+ HandShowRingL = 0x20ul << 24,
+ HandShowRingR = 0x40ul << 24,
+ _31 = 0x80ul << 24,
+ HandsMask = 0xFFul << 24,
+
+ FeetEnabled = 0x01ul << 32,
+ FeetHideKnee = 0x02ul << 32,
+ FeetHideCalf = 0x04ul << 32,
+ FeetHideAnkle = 0x08ul << 32,
+ _36 = 0x10ul << 32,
+ _37 = 0x20ul << 32,
+ _38 = 0x40ul << 32,
+ _39 = 0x80ul << 32,
+ FeetMask = 0xFFul << 32,
+
+ HeadEnabled = 0x00_00_01ul << 40,
+ HeadHideScalp = 0x00_00_02ul << 40,
+ HeadHideHair = 0x00_00_04ul << 40,
+ HeadShowHairOverride = 0x00_00_08ul << 40,
+ HeadHideNeck = 0x00_00_10ul << 40,
+ HeadShowNecklace = 0x00_00_20ul << 40,
+ _46 = 0x00_00_40ul << 40,
+ HeadShowEarrings = 0x00_00_80ul << 40,
+ HeadShowEarringsHuman = 0x00_01_00ul << 40,
+ HeadShowEarringsAura = 0x00_02_00ul << 40,
+ HeadShowEarHuman = 0x00_04_00ul << 40,
+ HeadShowEarMiqote = 0x00_08_00ul << 40,
+ HeadShowEarAuRa = 0x00_10_00ul << 40,
+ HeadShowEarViera = 0x00_20_00ul << 40,
+ _54 = 0x00_40_00ul << 40,
+ _55 = 0x00_80_00ul << 40,
+ HeadShowHrothgarHat = 0x01_00_00ul << 40,
+ HeadShowVieraHat = 0x02_00_00ul << 40,
+ _58 = 0x04_00_00ul << 40,
+ _59 = 0x08_00_00ul << 40,
+ _60 = 0x10_00_00ul << 40,
+ _61 = 0x20_00_00ul << 40,
+ _62 = 0x40_00_00ul << 40,
+ _63 = 0x80_00_00ul << 40,
+ HeadMask = 0xFF_FF_FFul << 40,
+ }
+
+ public static class Eqp
+ {
+ public static (int, int) BytesAndOffset( EquipSlot slot )
+ {
+ return slot switch
+ {
+ EquipSlot.Body => ( 2, 0 ),
+ EquipSlot.Legs => ( 1, 2 ),
+ EquipSlot.Hands => ( 1, 3 ),
+ EquipSlot.Feet => ( 1, 4 ),
+ EquipSlot.Head => ( 3, 5 ),
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ public static EqpEntry FromSlotAndBytes( EquipSlot slot, byte[] value )
+ {
+ EqpEntry ret = 0;
+ var (bytes, offset) = BytesAndOffset( slot );
+ if( bytes != value.Length )
+ {
+ throw new ArgumentException();
+ }
+
+ for( var i = 0; i < bytes; ++i )
+ {
+ ret |= ( EqpEntry )( ( ulong )value[ i ] << ( ( offset + i ) * 8 ) );
+ }
+
+ return ret;
+ }
+
+ public static EqpEntry Mask( EquipSlot slot )
+ {
+ return slot switch
+ {
+ EquipSlot.Body => EqpEntry.BodyMask,
+ EquipSlot.Head => EqpEntry.HeadMask,
+ EquipSlot.Legs => EqpEntry.LegsMask,
+ EquipSlot.Feet => EqpEntry.FeetMask,
+ EquipSlot.Hands => EqpEntry.HandsMask,
+ _ => 0,
+ };
+ }
+
+ public static EquipSlot ToEquipSlot( this EqpEntry entry )
+ {
+ return entry switch
+ {
+ EqpEntry.BodyEnabled => EquipSlot.Body,
+ EqpEntry.BodyHideWaist => EquipSlot.Body,
+ EqpEntry._2 => EquipSlot.Body,
+ EqpEntry.BodyHideGlovesS => EquipSlot.Body,
+ EqpEntry._4 => EquipSlot.Body,
+ EqpEntry.BodyHideGlovesM => EquipSlot.Body,
+ EqpEntry.BodyHideGlovesL => EquipSlot.Body,
+ EqpEntry.BodyHideGorget => EquipSlot.Body,
+ EqpEntry.BodyShowLeg => EquipSlot.Body,
+ EqpEntry.BodyShowHand => EquipSlot.Body,
+ EqpEntry.BodyShowHead => EquipSlot.Body,
+ EqpEntry.BodyShowNecklace => EquipSlot.Body,
+ EqpEntry.BodyShowBracelet => EquipSlot.Body,
+ EqpEntry.BodyShowTail => EquipSlot.Body,
+ EqpEntry.DisableBreastPhysics => EquipSlot.Body,
+ EqpEntry._15 => EquipSlot.Body,
+
+ EqpEntry.LegsEnabled => EquipSlot.Legs,
+ EqpEntry.LegsHideKneePads => EquipSlot.Legs,
+ EqpEntry.LegsHideBootsS => EquipSlot.Legs,
+ EqpEntry.LegsHideBootsM => EquipSlot.Legs,
+ EqpEntry._20 => EquipSlot.Legs,
+ EqpEntry.LegsShowFoot => EquipSlot.Legs,
+ EqpEntry.LegsShowTail => EquipSlot.Legs,
+ EqpEntry._23 => EquipSlot.Legs,
+
+ EqpEntry.HandsEnabled => EquipSlot.Hands,
+ EqpEntry.HandsHideElbow => EquipSlot.Hands,
+ EqpEntry.HandsHideForearm => EquipSlot.Hands,
+ EqpEntry._27 => EquipSlot.Hands,
+ EqpEntry.HandShowBracelet => EquipSlot.Hands,
+ EqpEntry.HandShowRingL => EquipSlot.Hands,
+ EqpEntry.HandShowRingR => EquipSlot.Hands,
+ EqpEntry._31 => EquipSlot.Hands,
+
+ EqpEntry.FeetEnabled => EquipSlot.Feet,
+ EqpEntry.FeetHideKnee => EquipSlot.Feet,
+ EqpEntry.FeetHideCalf => EquipSlot.Feet,
+ EqpEntry.FeetHideAnkle => EquipSlot.Feet,
+ EqpEntry._36 => EquipSlot.Feet,
+ EqpEntry._37 => EquipSlot.Feet,
+ EqpEntry._38 => EquipSlot.Feet,
+ EqpEntry._39 => EquipSlot.Feet,
+
+ EqpEntry.HeadEnabled => EquipSlot.Head,
+ EqpEntry.HeadHideScalp => EquipSlot.Head,
+ EqpEntry.HeadHideHair => EquipSlot.Head,
+ EqpEntry.HeadShowHairOverride => EquipSlot.Head,
+ EqpEntry.HeadHideNeck => EquipSlot.Head,
+ EqpEntry.HeadShowNecklace => EquipSlot.Head,
+ EqpEntry._46 => EquipSlot.Head,
+ EqpEntry.HeadShowEarrings => EquipSlot.Head,
+ EqpEntry.HeadShowEarringsHuman => EquipSlot.Head,
+ EqpEntry.HeadShowEarringsAura => EquipSlot.Head,
+ EqpEntry.HeadShowEarHuman => EquipSlot.Head,
+ EqpEntry.HeadShowEarMiqote => EquipSlot.Head,
+ EqpEntry.HeadShowEarAuRa => EquipSlot.Head,
+ EqpEntry.HeadShowEarViera => EquipSlot.Head,
+ EqpEntry._54 => EquipSlot.Head,
+ EqpEntry._55 => EquipSlot.Head,
+ EqpEntry.HeadShowHrothgarHat => EquipSlot.Head,
+ EqpEntry.HeadShowVieraHat => EquipSlot.Head,
+ EqpEntry._58 => EquipSlot.Head,
+ EqpEntry._59 => EquipSlot.Head,
+ EqpEntry._60 => EquipSlot.Head,
+ EqpEntry._61 => EquipSlot.Head,
+ EqpEntry._62 => EquipSlot.Head,
+ EqpEntry._63 => EquipSlot.Head,
+
+ _ => EquipSlot.Unknown,
+ };
+ }
+
+ public static string ToLocalName( this EqpEntry entry )
+ {
+ return entry switch
+ {
+ EqpEntry.BodyEnabled => "Enabled",
+ EqpEntry.BodyHideWaist => "Hide Waist",
+ EqpEntry._2 => "Unknown 2",
+ EqpEntry.BodyHideGlovesS => "Hide Small Gloves",
+ EqpEntry._4 => "Unknown 4",
+ EqpEntry.BodyHideGlovesM => "Hide Medium Gloves",
+ EqpEntry.BodyHideGlovesL => "Hide Large Gloves",
+ EqpEntry.BodyHideGorget => "Hide Gorget",
+ EqpEntry.BodyShowLeg => "Show Legs",
+ EqpEntry.BodyShowHand => "Show Hands",
+ EqpEntry.BodyShowHead => "Show Head",
+ EqpEntry.BodyShowNecklace => "Show Necklace",
+ EqpEntry.BodyShowBracelet => "Show Bracelet",
+ EqpEntry.BodyShowTail => "Show Tail",
+ EqpEntry.DisableBreastPhysics => "Disable Breast Physics",
+ EqpEntry._15 => "Unknown 15",
+
+ EqpEntry.LegsEnabled => "Enabled",
+ EqpEntry.LegsHideKneePads => "Hide Knee Pads",
+ EqpEntry.LegsHideBootsS => "Hide Small Boots",
+ EqpEntry.LegsHideBootsM => "Hide Medium Boots",
+ EqpEntry._20 => "Unknown 20",
+ EqpEntry.LegsShowFoot => "Show Foot",
+ EqpEntry.LegsShowTail => "Show Tail",
+ EqpEntry._23 => "Unknown 23",
+
+ EqpEntry.HandsEnabled => "Enabled",
+ EqpEntry.HandsHideElbow => "Hide Elbow",
+ EqpEntry.HandsHideForearm => "Hide Forearm",
+ EqpEntry._27 => "Unknown 27",
+ EqpEntry.HandShowBracelet => "Show Bracelet",
+ EqpEntry.HandShowRingL => "Show Left Ring",
+ EqpEntry.HandShowRingR => "Show Right Ring",
+ EqpEntry._31 => "Unknown 31",
+
+ EqpEntry.FeetEnabled => "Enabled",
+ EqpEntry.FeetHideKnee => "Hide Knees",
+ EqpEntry.FeetHideCalf => "Hide Calves",
+ EqpEntry.FeetHideAnkle => "Hide Ankles",
+ EqpEntry._36 => "Unknown 36",
+ EqpEntry._37 => "Unknown 37",
+ EqpEntry._38 => "Unknown 38",
+ EqpEntry._39 => "Unknown 39",
+
+ EqpEntry.HeadEnabled => "Enabled",
+ EqpEntry.HeadHideScalp => "Hide Scalp",
+ EqpEntry.HeadHideHair => "Hide Hair",
+ EqpEntry.HeadShowHairOverride => "Show Hair Override",
+ EqpEntry.HeadHideNeck => "Hide Neck",
+ EqpEntry.HeadShowNecklace => "Show Necklace",
+ EqpEntry._46 => "Unknown 46",
+ EqpEntry.HeadShowEarrings => "Show Earrings",
+ EqpEntry.HeadShowEarringsHuman => "Show Earrings (Human)",
+ EqpEntry.HeadShowEarringsAura => "Show Earrings (Au Ra)",
+ EqpEntry.HeadShowEarHuman => "Show Ears (Human)",
+ EqpEntry.HeadShowEarMiqote => "Show Ears (Miqo'te)",
+ EqpEntry.HeadShowEarAuRa => "Show Ears (Au Ra)",
+ EqpEntry.HeadShowEarViera => "Show Ears (Viera)",
+ EqpEntry._54 => "Unknown 54",
+ EqpEntry._55 => "Unknown 55",
+ EqpEntry.HeadShowHrothgarHat => "Show on Hrothgar",
+ EqpEntry.HeadShowVieraHat => "Show on Viera",
+ EqpEntry._58 => "Unknown 58",
+ EqpEntry._59 => "Unknown 59",
+ EqpEntry._60 => "Unknown 60",
+ EqpEntry._61 => "Unknown 61",
+ EqpEntry._62 => "Unknown 62",
+ EqpEntry._63 => "Unknown 63",
+
+ _ => throw new InvalidEnumArgumentException(),
+ };
+ }
+
+ private static EqpEntry[] GetEntriesForSlot( EquipSlot slot )
+ {
+ return ( ( EqpEntry[] )Enum.GetValues( typeof( EqpEntry ) ) )
+ .Where( e => e.ToEquipSlot() == slot )
+ .ToArray();
+ }
+
+ public static readonly EqpEntry[] EqpAttributesBody = GetEntriesForSlot( EquipSlot.Body );
+ public static readonly EqpEntry[] EqpAttributesLegs = GetEntriesForSlot( EquipSlot.Legs );
+ public static readonly EqpEntry[] EqpAttributesHands = GetEntriesForSlot( EquipSlot.Hands );
+ public static readonly EqpEntry[] EqpAttributesFeet = GetEntriesForSlot( EquipSlot.Feet );
+ public static readonly EqpEntry[] EqpAttributesHead = GetEntriesForSlot( EquipSlot.Head );
+
+ public static IReadOnlyDictionary< EquipSlot, EqpEntry[] > EqpAttributes = new Dictionary< EquipSlot, EqpEntry[] >()
+ {
+ [ EquipSlot.Body ] = EqpAttributesBody,
+ [ EquipSlot.Legs ] = EqpAttributesLegs,
+ [ EquipSlot.Hands ] = EqpAttributesHands,
+ [ EquipSlot.Feet ] = EqpAttributesFeet,
+ [ EquipSlot.Head ] = EqpAttributesHead,
+ };
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/GameObjectInfo.cs b/Penumbra.GameData/Structs/GameObjectInfo.cs
new file mode 100644
index 00000000..80b6c792
--- /dev/null
+++ b/Penumbra.GameData/Structs/GameObjectInfo.cs
@@ -0,0 +1,160 @@
+using System;
+using System.Runtime.InteropServices;
+using Dalamud;
+using Penumbra.GameData.Enums;
+
+namespace Penumbra.GameData.Structs
+{
+ [StructLayout( LayoutKind.Explicit )]
+ public struct GameObjectInfo : IComparable
+ {
+ public static GameObjectInfo Equipment( FileType type, ushort setId, GenderRace gr = GenderRace.Unknown
+ , EquipSlot slot = EquipSlot.Unknown, byte variant = 0 )
+ => new()
+ {
+ FileType = type,
+ ObjectType = slot.IsAccessory() ? ObjectType.Accessory : ObjectType.Equipment,
+ PrimaryId = setId,
+ GenderRace = gr,
+ Variant = variant,
+ EquipSlot = slot,
+ };
+
+ public static GameObjectInfo Weapon( FileType type, ushort setId, ushort weaponId, byte variant = 0 )
+ => new()
+ {
+ FileType = type,
+ ObjectType = ObjectType.Weapon,
+ PrimaryId = setId,
+ SecondaryId = weaponId,
+ Variant = variant,
+ };
+
+ public static GameObjectInfo Customization( FileType type, CustomizationType customizationType, ushort id = 0
+ , GenderRace gr = GenderRace.Unknown, BodySlot bodySlot = BodySlot.Unknown, byte variant = 0 )
+ => new()
+ {
+ FileType = type,
+ ObjectType = ObjectType.Character,
+ PrimaryId = id,
+ GenderRace = gr,
+ BodySlot = bodySlot,
+ Variant = variant,
+ CustomizationType = customizationType,
+ };
+
+ public static GameObjectInfo Monster( FileType type, ushort monsterId, ushort bodyId, byte variant = 0 )
+ => new()
+ {
+ FileType = type,
+ ObjectType = ObjectType.Monster,
+ PrimaryId = monsterId,
+ SecondaryId = bodyId,
+ Variant = variant,
+ };
+
+ public static GameObjectInfo DemiHuman( FileType type, ushort demiHumanId, ushort bodyId, EquipSlot slot = EquipSlot.Unknown,
+ byte variant = 0
+ )
+ => new()
+ {
+ FileType = type,
+ ObjectType = ObjectType.DemiHuman,
+ PrimaryId = demiHumanId,
+ SecondaryId = bodyId,
+ Variant = variant,
+ EquipSlot = slot,
+ };
+
+ public static GameObjectInfo Map( FileType type, byte c1, byte c2, byte c3, byte c4, byte variant, byte suffix = 0 )
+ => new()
+ {
+ FileType = type,
+ ObjectType = ObjectType.Map,
+ MapC1 = c1,
+ MapC2 = c2,
+ MapC3 = c3,
+ MapC4 = c4,
+ MapSuffix = suffix,
+ Variant = variant,
+ };
+
+ public static GameObjectInfo Icon( FileType type, uint iconId, bool hq, ClientLanguage lang = ClientLanguage.English )
+ => new()
+ {
+ FileType = type,
+ ObjectType = ObjectType.Map,
+ IconId = iconId,
+ IconHq = hq,
+ Language = lang,
+ };
+
+
+ [FieldOffset( 0 )]
+ public readonly ulong Identifier;
+
+ [FieldOffset( 0 )]
+ public FileType FileType;
+
+ [FieldOffset( 1 )]
+ public ObjectType ObjectType;
+
+
+ [FieldOffset( 2 )]
+ public ushort PrimaryId; // Equipment, Weapon, Customization, Monster, DemiHuman
+
+ [FieldOffset( 2 )]
+ public uint IconId; // Icon
+
+ [FieldOffset( 2 )]
+ public byte MapC1; // Map
+
+ [FieldOffset( 3 )]
+ public byte MapC2; // Map
+
+ [FieldOffset( 4 )]
+ public ushort SecondaryId; // Weapon, Monster, Demihuman
+
+ [FieldOffset( 4 )]
+ public byte MapC3; // Map
+
+ [FieldOffset( 4 )]
+ private byte _genderRaceByte; // Equipment, Customization
+
+ public GenderRace GenderRace
+ {
+ get => Names.GenderRaceFromByte( _genderRaceByte );
+ set => _genderRaceByte = value.ToByte();
+ }
+
+ [FieldOffset( 5 )]
+ public BodySlot BodySlot; // Customization
+
+ [FieldOffset( 5 )]
+ public byte MapC4; // Map
+
+ [FieldOffset( 6 )]
+ public byte Variant; // Equipment, Weapon, Customization, Map, Monster, Demihuman
+
+ [FieldOffset( 6 )]
+ public bool IconHq; // Icon
+
+ [FieldOffset( 7 )]
+ public EquipSlot EquipSlot; // Equipment, Demihuman
+
+ [FieldOffset( 7 )]
+ public CustomizationType CustomizationType; // Customization
+
+ [FieldOffset( 7 )]
+ public ClientLanguage Language; // Icon
+
+ [FieldOffset( 7 )]
+ public byte MapSuffix;
+
+ public override int GetHashCode()
+ => Identifier.GetHashCode();
+
+ public int CompareTo( object? r )
+ => Identifier.CompareTo( r );
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/GmpEntry.cs b/Penumbra.GameData/Structs/GmpEntry.cs
new file mode 100644
index 00000000..be9a7b58
--- /dev/null
+++ b/Penumbra.GameData/Structs/GmpEntry.cs
@@ -0,0 +1,92 @@
+using System.IO;
+
+namespace Penumbra.GameData.Structs
+{
+ public struct GmpEntry
+ {
+ public bool Enabled
+ {
+ get => ( Value & 1 ) == 1;
+ set
+ {
+ if( value )
+ {
+ Value |= 1ul;
+ }
+ else
+ {
+ Value &= ~1ul;
+ }
+ }
+ }
+
+ public bool Animated
+ {
+ get => ( Value & 2 ) == 2;
+ set
+ {
+ if( value )
+ {
+ Value |= 2ul;
+ }
+ else
+ {
+ Value &= ~2ul;
+ }
+ }
+ }
+
+ public ushort RotationA
+ {
+ get => ( ushort )( ( Value >> 2 ) & 0x3FF );
+ set => Value = ( Value & ~0xFFCul ) | ( ( value & 0x3FFul ) << 2 );
+ }
+
+ public ushort RotationB
+ {
+ get => ( ushort )( ( Value >> 12 ) & 0x3FF );
+ set => Value = ( Value & ~0x3FF000ul ) | ( ( value & 0x3FFul ) << 12 );
+ }
+
+ public ushort RotationC
+ {
+ get => ( ushort )( ( Value >> 22 ) & 0x3FF );
+ set => Value = ( Value & ~0xFFC00000ul ) | ( ( value & 0x3FFul ) << 22 );
+ }
+
+ public byte UnknownA
+ {
+ get => ( byte )( ( Value >> 32 ) & 0x0F );
+ set => Value = ( Value & ~0x0F00000000ul ) | ( ( value & 0x0Ful ) << 32 );
+ }
+
+ public byte UnknownB
+ {
+ get => ( byte )( ( Value >> 36 ) & 0x0F );
+ set => Value = ( Value & ~0xF000000000ul ) | ( ( value & 0x0Ful ) << 36 );
+ }
+
+ public byte UnknownTotal
+ {
+ get => ( byte )( ( Value >> 32 ) & 0xFF );
+ set => Value = ( Value & ~0xFF00000000ul ) | ( ( value & 0xFFul ) << 32 );
+ }
+
+ public ulong Value { get; set; }
+
+ public static GmpEntry FromTexToolsMeta( byte[] data )
+ {
+ GmpEntry ret = new();
+ using var reader = new BinaryReader( new MemoryStream( data ) );
+ ret.Value = reader.ReadUInt32();
+ ret.UnknownTotal = data[ 4 ];
+ return ret;
+ }
+
+ public static implicit operator ulong( GmpEntry entry )
+ => entry.Value;
+
+ public static explicit operator GmpEntry( ulong entry )
+ => new() { Value = entry };
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/RspEntry.cs b/Penumbra.GameData/Structs/RspEntry.cs
new file mode 100644
index 00000000..80f02144
--- /dev/null
+++ b/Penumbra.GameData/Structs/RspEntry.cs
@@ -0,0 +1,58 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Runtime.InteropServices;
+using Penumbra.GameData.Enums;
+
+namespace Penumbra.GameData.Structs
+{
+ [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+ public readonly struct RspEntry
+ {
+ public const int ByteSize = ( int )RspAttribute.NumAttributes * 4;
+
+ private readonly float[] Attributes;
+
+ public RspEntry( RspEntry copy )
+ => Attributes = ( float[] )copy.Attributes.Clone();
+
+ public RspEntry( byte[] bytes, int offset )
+ {
+ if( offset < 0 || offset + ByteSize > bytes.Length )
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ Attributes = new float[( int )RspAttribute.NumAttributes];
+ using MemoryStream s = new( bytes ) { Position = offset };
+ using BinaryReader br = new( s );
+ for( var i = 0; i < ( int )RspAttribute.NumAttributes; ++i )
+ {
+ Attributes[ i ] = br.ReadSingle();
+ }
+ }
+
+ private static int ToIndex( RspAttribute attribute )
+ => attribute < RspAttribute.NumAttributes && attribute >= 0
+ ? ( int )attribute
+ : throw new InvalidEnumArgumentException();
+
+ public float this[ RspAttribute attribute ]
+ {
+ get => Attributes[ ToIndex( attribute ) ];
+ set => Attributes[ ToIndex( attribute ) ] = value;
+ }
+
+ public byte[] ToBytes()
+ {
+ using var s = new MemoryStream( ByteSize );
+ using var bw = new BinaryWriter( s );
+ foreach( var attribute in Attributes )
+ {
+ bw.Write( attribute );
+ }
+
+ return s.ToArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/SetId.cs b/Penumbra.GameData/Structs/SetId.cs
new file mode 100644
index 00000000..a2483538
--- /dev/null
+++ b/Penumbra.GameData/Structs/SetId.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Penumbra.GameData.Structs
+{
+ public readonly struct SetId : IComparable< SetId >
+ {
+ public readonly ushort Value;
+
+ public SetId( ushort value )
+ => Value = value;
+
+ public static implicit operator SetId( ushort id )
+ => new( id );
+
+ public static explicit operator ushort( SetId id )
+ => id.Value;
+
+ public override string ToString()
+ => Value.ToString();
+
+ public int CompareTo( SetId other )
+ => Value.CompareTo( other.Value );
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/StainId.cs b/Penumbra.GameData/Structs/StainId.cs
new file mode 100644
index 00000000..74a479a1
--- /dev/null
+++ b/Penumbra.GameData/Structs/StainId.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Penumbra.GameData.Structs
+{
+ public readonly struct StainId : IEquatable< StainId >
+ {
+ public readonly byte Value;
+
+ public StainId( byte value )
+ => Value = value;
+
+ public static implicit operator StainId( byte id )
+ => new( id );
+
+ public static explicit operator byte( StainId id )
+ => id.Value;
+
+ public override string ToString()
+ => Value.ToString();
+
+ public bool Equals( StainId other )
+ => Value == other.Value;
+
+ public override bool Equals( object? obj )
+ => obj is StainId other && Equals( other );
+
+ public override int GetHashCode()
+ => Value.GetHashCode();
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Structs/WeaponType.cs b/Penumbra.GameData/Structs/WeaponType.cs
new file mode 100644
index 00000000..a5fa6107
--- /dev/null
+++ b/Penumbra.GameData/Structs/WeaponType.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Penumbra.GameData.Structs
+{
+ public readonly struct WeaponType : IEquatable< WeaponType >
+ {
+ public readonly ushort Value;
+
+ public WeaponType( ushort value )
+ => Value = value;
+
+ public static implicit operator WeaponType( ushort id )
+ => new( id );
+
+ public static explicit operator ushort( WeaponType id )
+ => id.Value;
+
+ public override string ToString()
+ => Value.ToString();
+
+ public bool Equals( WeaponType other )
+ => Value == other.Value;
+
+ public override bool Equals( object? obj )
+ => obj is WeaponType other && Equals( other );
+
+ public override int GetHashCode()
+ => Value.GetHashCode();
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.GameData/Util/GamePath.cs b/Penumbra.GameData/Util/GamePath.cs
new file mode 100644
index 00000000..b602d8d6
--- /dev/null
+++ b/Penumbra.GameData/Util/GamePath.cs
@@ -0,0 +1,105 @@
+using System;
+using System.IO;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Penumbra.GameData.Util
+{
+ public readonly struct GamePath : IComparable
+ {
+ public const int MaxGamePathLength = 256;
+
+ private readonly string _path;
+
+ private GamePath( string path, bool _ )
+ => _path = path;
+
+ public GamePath( string? path )
+ {
+ if( path != null && path.Length < MaxGamePathLength )
+ {
+ _path = Lower( Trim( ReplaceSlash( path ) ) );
+ }
+ else
+ {
+ _path = "";
+ }
+ }
+
+ public GamePath( FileInfo file, DirectoryInfo baseDir )
+ => _path = CheckPre( file, baseDir ) ? Lower( Trim( ReplaceSlash( Substring( file, baseDir ) ) ) ) : "";
+
+ private static bool CheckPre( FileInfo file, DirectoryInfo baseDir )
+ => file.FullName.StartsWith( baseDir.FullName ) && file.FullName.Length < MaxGamePathLength;
+
+ private static string Substring( FileInfo file, DirectoryInfo baseDir )
+ => file.FullName.Substring( baseDir.FullName.Length );
+
+ private static string ReplaceSlash( string path )
+ => path.Replace( '\\', '/' );
+
+ private static string Trim( string path )
+ => path.TrimStart( '/' );
+
+ private static string Lower( string path )
+ => path.ToLowerInvariant();
+
+ public static GamePath GenerateUnchecked( string path )
+ => new( path, true );
+
+ public static GamePath GenerateUncheckedLower( string path )
+ => new( Lower( path ), true );
+
+ public static implicit operator string( GamePath gamePath )
+ => gamePath._path;
+
+ public static explicit operator GamePath( string gamePath )
+ => new( gamePath );
+
+ public bool Empty
+ => _path.Length == 0;
+
+ public string Filename()
+ {
+ var idx = _path.LastIndexOf( "/", StringComparison.Ordinal );
+ return idx == -1 ? _path : idx == _path.Length - 1 ? "" : _path.Substring( idx + 1 );
+ }
+
+ public int CompareTo( object? rhs )
+ {
+ return rhs switch
+ {
+ string path => string.Compare( _path, path, StringComparison.InvariantCulture ),
+ GamePath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ),
+ _ => -1,
+ };
+ }
+
+ public override string ToString()
+ => _path;
+ }
+
+ public class GamePathConverter : JsonConverter
+ {
+ public override bool CanConvert( Type objectType )
+ => objectType == typeof( GamePath );
+
+ public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer )
+ {
+ var token = JToken.Load( reader );
+ return token.ToObject< GamePath >();
+ }
+
+ public override bool CanWrite
+ => true;
+
+ public override void WriteJson( JsonWriter writer, object? value, JsonSerializer serializer )
+ {
+ if( value != null )
+ {
+ var v = ( GamePath )value;
+ serializer.Serialize( writer, v.ToString() );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.PlayerWatch/CharacterFactory.cs b/Penumbra.PlayerWatch/CharacterFactory.cs
new file mode 100644
index 00000000..9c18c29e
--- /dev/null
+++ b/Penumbra.PlayerWatch/CharacterFactory.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Reflection;
+using Dalamud.Game.ClientState.Objects.Enums;
+using Dalamud.Game.ClientState.Objects.SubKinds;
+using Dalamud.Game.ClientState.Objects.Types;
+
+namespace Penumbra.PlayerWatch
+{
+ public static class CharacterFactory
+ {
+ private static ConstructorInfo? _characterConstructor = null;
+
+ private static void Initialize()
+ {
+ _characterConstructor ??= typeof( Character ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new[]
+ {
+ typeof( IntPtr ),
+ }, null )!;
+ }
+
+ private static Character Character( IntPtr address )
+ {
+ Initialize();
+ return ( Character )_characterConstructor?.Invoke( new object[]
+ {
+ address,
+ } )!;
+ }
+
+ public static Character? Convert( GameObject? actor )
+ {
+ if( actor == null )
+ {
+ return null;
+ }
+
+ return actor switch
+ {
+ PlayerCharacter p => p,
+ BattleChara b => b,
+ _ => actor.ObjectKind switch
+ {
+ ObjectKind.BattleNpc => Character( actor.Address ),
+ ObjectKind.Companion => Character( actor.Address ),
+ ObjectKind.Retainer => Character( actor.Address ),
+ ObjectKind.EventNpc => Character( actor.Address ),
+ _ => null,
+ },
+ };
+ }
+ }
+
+ public static class GameObjectExtensions
+ {
+ private const int ModelTypeOffset = 0x01B4;
+
+ public static unsafe int ModelType( this GameObject actor )
+ => *( int* )( actor.Address + ModelTypeOffset );
+
+ public static unsafe void SetModelType( this GameObject actor, int value )
+ => *( int* )( actor.Address + ModelTypeOffset ) = value;
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.PlayerWatch/IPlayerWatcher.cs b/Penumbra.PlayerWatch/IPlayerWatcher.cs
new file mode 100644
index 00000000..8a884bc1
--- /dev/null
+++ b/Penumbra.PlayerWatch/IPlayerWatcher.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using Dalamud.Game.ClientState.Objects.Types;
+using Penumbra.GameData.Structs;
+
+namespace Penumbra.PlayerWatch
+{
+ public delegate void PlayerChange( Character actor );
+
+ public interface IPlayerWatcherBase : IDisposable
+ {
+ public int Version { get; }
+ public bool Valid { get; }
+ }
+
+ public interface IPlayerWatcher : IPlayerWatcherBase
+ {
+ public event PlayerChange? PlayerChanged;
+ public bool Active { get; }
+
+ public void Enable();
+ public void Disable();
+ public void SetStatus( bool enabled );
+
+ public void AddPlayerToWatch( string playerName );
+ public void RemovePlayerFromWatch( string playerName );
+ public CharacterEquipment UpdatePlayerWithoutEvent( Character actor );
+
+ public IEnumerable< (string, (uint, CharacterEquipment)[]) > WatchedPlayers();
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.PlayerWatch/Penumbra.PlayerWatch.csproj b/Penumbra.PlayerWatch/Penumbra.PlayerWatch.csproj
new file mode 100644
index 00000000..f3449ad3
--- /dev/null
+++ b/Penumbra.PlayerWatch/Penumbra.PlayerWatch.csproj
@@ -0,0 +1,40 @@
+
+
+ net5.0-windows
+ preview
+ x64
+ Penumbra.PlayerWatch
+ absolute gangstas
+ Penumbra
+ Copyright © 2020
+ 1.0.0.0
+ 1.0.0.0
+ bin\$(Configuration)\
+ true
+ enable
+
+
+
+ full
+ DEBUG;TRACE
+
+
+
+ pdbonly
+
+
+
+ $(MSBuildWarningsAsMessages);MSB3277
+
+
+
+
+ $(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll
+ False
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Penumbra.PlayerWatch/PlayerWatchBase.cs b/Penumbra.PlayerWatch/PlayerWatchBase.cs
new file mode 100644
index 00000000..3045af88
--- /dev/null
+++ b/Penumbra.PlayerWatch/PlayerWatchBase.cs
@@ -0,0 +1,311 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Dalamud.Game;
+using Dalamud.Game.ClientState;
+using Dalamud.Game.ClientState.Objects;
+using Dalamud.Game.ClientState.Objects.Enums;
+using Dalamud.Game.ClientState.Objects.Types;
+using Dalamud.Logging;
+using Penumbra.GameData.Structs;
+
+namespace Penumbra.PlayerWatch
+{
+ internal readonly struct WatchedPlayer
+ {
+ public readonly Dictionary< uint, CharacterEquipment > FoundActors;
+ public readonly HashSet< PlayerWatcher > RegisteredWatchers;
+
+ public WatchedPlayer( PlayerWatcher watcher )
+ {
+ FoundActors = new Dictionary< uint, CharacterEquipment >(4);
+ RegisteredWatchers = new HashSet< PlayerWatcher >{ watcher };
+ }
+ }
+
+ internal class PlayerWatchBase : IDisposable
+ {
+ public const int GPosePlayerIdx = 201;
+ public const int GPoseTableEnd = GPosePlayerIdx + 48;
+ private const int ObjectsPerFrame = 32;
+
+ private readonly Framework _framework;
+ private readonly ClientState _clientState;
+ private readonly ObjectTable _objects;
+ internal readonly HashSet< PlayerWatcher > RegisteredWatchers = new();
+ internal readonly Dictionary< string, WatchedPlayer > Equip = new();
+ private int _frameTicker;
+ private bool _inGPose;
+ private bool _enabled;
+ private bool _cancel;
+
+ internal PlayerWatchBase( Framework framework, ClientState clientState, ObjectTable objects )
+ {
+ _framework = framework;
+ _clientState = clientState;
+ _objects = objects;
+ }
+
+ internal void RegisterWatcher( PlayerWatcher watcher )
+ {
+ RegisteredWatchers.Add( watcher );
+ if( watcher.Active )
+ {
+ EnablePlayerWatch();
+ }
+ }
+
+ internal void UnregisterWatcher( PlayerWatcher watcher )
+ {
+ if( RegisteredWatchers.Remove( watcher ) )
+ {
+ foreach( var (key, value) in Equip.ToArray() )
+ {
+ if( value.RegisteredWatchers.Remove( watcher ) && value.RegisteredWatchers.Count == 0 )
+ {
+ Equip.Remove( key );
+ }
+ }
+ }
+
+ CheckActiveStatus();
+ }
+
+ internal void CheckActiveStatus()
+ {
+ if( RegisteredWatchers.Any( w => w.Active ) )
+ {
+ EnablePlayerWatch();
+ }
+ else
+ {
+ DisablePlayerWatch();
+ }
+ }
+
+ private static uint GetId( GameObject actor )
+ => actor.ObjectId ^ actor.OwnerId;
+
+ internal CharacterEquipment UpdatePlayerWithoutEvent( Character actor )
+ {
+ var name = actor.Name.ToString();
+ var equipment = new CharacterEquipment( actor );
+ if (Equip.TryGetValue( name, out var watched ))
+ {
+ watched.FoundActors[ GetId( actor ) ] = equipment;
+ }
+
+ return equipment;
+ }
+
+ internal void AddPlayerToWatch( string playerName, PlayerWatcher watcher )
+ {
+ if( Equip.TryGetValue( playerName, out var items ) )
+ {
+ items.RegisteredWatchers.Add( watcher );
+ }
+ else
+ {
+ Equip[ playerName ] = new WatchedPlayer( watcher );
+ }
+ }
+
+ public void RemovePlayerFromWatch( string playerName, PlayerWatcher watcher )
+ {
+ if( Equip.TryGetValue( playerName, out var items ) )
+ {
+ if( items.RegisteredWatchers.Remove( watcher ) && items.RegisteredWatchers.Count == 0 )
+ {
+ Equip.Remove( playerName );
+ }
+ }
+ }
+
+ internal void EnablePlayerWatch()
+ {
+ if( !_enabled )
+ {
+ _enabled = true;
+ _framework.Update += OnFrameworkUpdate;
+ _clientState.TerritoryChanged += OnTerritoryChange;
+ _clientState.Logout += OnLogout;
+ }
+ }
+
+ internal void DisablePlayerWatch()
+ {
+ if( _enabled )
+ {
+ _enabled = false;
+ _framework.Update -= OnFrameworkUpdate;
+ _clientState.TerritoryChanged -= OnTerritoryChange;
+ _clientState.Logout -= OnLogout;
+ }
+ }
+
+ public void Dispose()
+ => DisablePlayerWatch();
+
+ private void OnTerritoryChange( object? _1, ushort _2 )
+ => Clear();
+
+ private void OnLogout( object? _1, object? _2 )
+ => Clear();
+
+ internal void Clear()
+ {
+ PluginLog.Debug( "Clearing PlayerWatcher Store." );
+ _cancel = true;
+ foreach( var kvp in Equip )
+ {
+ kvp.Value.FoundActors.Clear();
+ }
+
+ _frameTicker = 0;
+ }
+
+ private static void TriggerEvents( IEnumerable< PlayerWatcher > watchers, Character player )
+ {
+ PluginLog.Debug( "Triggering events for {PlayerName} at {Address}.", player.Name, player.Address );
+ foreach( var watcher in watchers.Where( w => w.Active ) )
+ {
+ watcher.Trigger( player );
+ }
+ }
+
+ internal void TriggerGPose()
+ {
+ for( var i = GPosePlayerIdx; i < GPoseTableEnd; ++i )
+ {
+ var player = _objects[ i ];
+ if( player == null )
+ {
+ return;
+ }
+
+ if( Equip.TryGetValue( player.Name.ToString(), out var watcher ) )
+ {
+ TriggerEvents( watcher.RegisteredWatchers, ( Character )player );
+ }
+ }
+ }
+
+ private Character? CheckGPoseObject( GameObject player )
+ {
+ if( !_inGPose )
+ {
+ return CharacterFactory.Convert( player );
+ }
+
+ for( var i = GPosePlayerIdx; i < GPoseTableEnd; ++i )
+ {
+ var a = _objects[ i ];
+ if( a == null )
+ {
+ return CharacterFactory.Convert( player );
+ }
+
+ if( a.Name == player.Name )
+ {
+ return CharacterFactory.Convert( a );
+ }
+ }
+
+ return CharacterFactory.Convert( player )!;
+ }
+
+ private bool TryGetPlayer( GameObject gameObject, out WatchedPlayer watch )
+ {
+ watch = default;
+ var name = gameObject.Name.ToString();
+ return name.Length != 0 && Equip.TryGetValue( name, out watch );
+ }
+
+ private static bool InvalidObjectKind( ObjectKind kind )
+ {
+ return kind switch
+ {
+ ObjectKind.BattleNpc => false,
+ ObjectKind.EventNpc => false,
+ ObjectKind.Player => false,
+ ObjectKind.Retainer => false,
+ _ => true,
+ };
+ }
+
+ private GameObject? GetNextObject()
+ {
+ if( _frameTicker == GPosePlayerIdx - 1 )
+ {
+ _frameTicker = GPoseTableEnd;
+ }
+ else if( _frameTicker == _objects.Length - 1 )
+ {
+ _frameTicker = 0;
+ }
+ else
+ {
+ ++_frameTicker;
+ }
+
+ return _objects[ _frameTicker ];
+ }
+
+ private void OnFrameworkUpdate( object framework )
+ {
+ var newInGPose = _objects[ GPosePlayerIdx ] != null;
+
+ if( newInGPose != _inGPose )
+ {
+ if( newInGPose )
+ {
+ TriggerGPose();
+ }
+ else
+ {
+ Clear();
+ }
+
+ _inGPose = newInGPose;
+ }
+
+ for( var i = 0; i < ObjectsPerFrame; ++i )
+ {
+ var actor = GetNextObject();
+ if( actor == null
+ || InvalidObjectKind( actor.ObjectKind )
+ || !TryGetPlayer( actor, out var watch ) )
+ {
+ continue;
+ }
+
+ var character = CheckGPoseObject( actor );
+ if( _cancel )
+ {
+ _cancel = false;
+ return;
+ }
+
+ if( character == null || character.ModelType() != 0 )
+ {
+ continue;
+ }
+
+ var id = GetId( character );
+ PluginLog.Verbose( "Comparing Gear for {PlayerName} ({Id}) at {Address}...", character.Name, id, character.Address);
+ if( !watch.FoundActors.TryGetValue( id, out var equip ) )
+ {
+ equip = new CharacterEquipment( character );
+ watch.FoundActors[ id ] = equip;
+ TriggerEvents( watch.RegisteredWatchers, character );
+ }
+ else if (!equip.CompareAndUpdate( character ))
+ {
+ TriggerEvents( watch.RegisteredWatchers, character );
+ }
+
+ break; // Only one comparison per frame.
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.PlayerWatch/PlayerWatcher.cs b/Penumbra.PlayerWatch/PlayerWatcher.cs
new file mode 100644
index 00000000..9eab7134
--- /dev/null
+++ b/Penumbra.PlayerWatch/PlayerWatcher.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Dalamud.Game;
+using Dalamud.Game.ClientState;
+using Dalamud.Game.ClientState.Objects;
+using Dalamud.Game.ClientState.Objects.Types;
+using Penumbra.GameData.Structs;
+
+namespace Penumbra.PlayerWatch
+{
+ public class PlayerWatcher : IPlayerWatcher
+ {
+ public int Version { get; } = 2;
+
+ private static PlayerWatchBase? _playerWatch;
+
+ public event PlayerChange? PlayerChanged;
+
+ public bool Active { get; set; } = true;
+
+ public bool Valid
+ => _playerWatch != null;
+
+ internal PlayerWatcher( Framework framework, ClientState clientState, ObjectTable objects )
+ {
+ _playerWatch ??= new PlayerWatchBase( framework, clientState, objects );
+ _playerWatch.RegisterWatcher( this );
+ }
+
+ public void Enable()
+ => SetStatus( true );
+
+ public void Disable()
+ => SetStatus( false );
+
+ public void SetStatus( bool enabled )
+ {
+ Active = enabled && Valid;
+ _playerWatch?.CheckActiveStatus();
+ }
+
+ internal void Trigger( Character actor )
+ => PlayerChanged?.Invoke( actor );
+
+ public void Dispose()
+ {
+ if( _playerWatch == null )
+ {
+ return;
+ }
+
+ Active = false;
+ PlayerChanged = null;
+ _playerWatch.UnregisterWatcher( this );
+ if( _playerWatch.RegisteredWatchers.Count == 0 )
+ {
+ _playerWatch.Dispose();
+ _playerWatch = null;
+ }
+ }
+
+ private void CheckValidity()
+ {
+ if( !Valid )
+ {
+ throw new Exception( $"PlayerWatch was already disposed." );
+ }
+ }
+
+ public void AddPlayerToWatch( string name )
+ {
+ CheckValidity();
+ _playerWatch!.AddPlayerToWatch( name, this );
+ }
+
+ public void RemovePlayerFromWatch( string playerName )
+ {
+ CheckValidity();
+ _playerWatch!.RemovePlayerFromWatch( playerName, this );
+ }
+
+ public CharacterEquipment UpdatePlayerWithoutEvent( Character actor )
+ {
+ CheckValidity();
+ return _playerWatch!.UpdatePlayerWithoutEvent( actor );
+ }
+
+ public IEnumerable< (string, (uint, CharacterEquipment)[]) > WatchedPlayers()
+ {
+ CheckValidity();
+ return _playerWatch!.Equip
+ .Where( kvp => kvp.Value.RegisteredWatchers.Contains( this ) )
+ .Select( kvp => ( kvp.Key, kvp.Value.FoundActors.Select( kvp2 => ( kvp2.Key, kvp2.Value ) ).ToArray() ) );
+ }
+ }
+
+ public static class PlayerWatchFactory
+ {
+ public static IPlayerWatcher Create( Framework framework, ClientState clientState, ObjectTable objects )
+ => new PlayerWatcher( framework, clientState, objects );
+ }
+}
\ No newline at end of file
diff --git a/Penumbra.String b/Penumbra.String
deleted file mode 160000
index 9bd016fb..00000000
--- a/Penumbra.String
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 9bd016fbef5fb2de467dd42165267fdd93cd9592
diff --git a/Penumbra.sln b/Penumbra.sln
index fbcd6080..58df4bf5 100644
--- a/Penumbra.sln
+++ b/Penumbra.sln
@@ -1,98 +1,41 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.2.32210.308
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra", "Penumbra\Penumbra.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F89C9EAE-25C8-43BE-8108-5921E5A93502}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
- .github\workflows\build.yml = .github\workflows\build.yml
- Penumbra\Penumbra.json = Penumbra\Penumbra.json
- .github\workflows\release.yml = .github\workflows\release.yml
- repo.json = repo.json
- .github\workflows\test_release.yml = .github\workflows\test_release.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.GameData", "Penumbra.GameData\Penumbra.GameData.csproj", "{EE551E87-FDB3-4612-B500-DC870C07C605}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OtterGui", "OtterGui\OtterGui.csproj", "{87750518-1A20-40B4-9FC1-22F906EFB290}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.Api", "Penumbra.Api\Penumbra.Api.csproj", "{1FE4D8DF-B56A-464F-B39E-CDC0ED4167D4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.String", "Penumbra.String\Penumbra.String.csproj", "{5549BAFD-6357-4B1A-800C-75AC36E5B76D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.CrashHandler", "Penumbra.CrashHandler\Penumbra.CrashHandler.csproj", "{EE834491-A98F-4395-BE0D-6861AE5AD953}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Schemas", "Schemas", "{BFEA7504-1210-4F79-A7FE-BF03B6567E33}"
- ProjectSection(SolutionItems) = preProject
- schemas\default_mod.json = schemas\default_mod.json
- schemas\group.json = schemas\group.json
- schemas\local_mod_data-v3.json = schemas\local_mod_data-v3.json
- schemas\mod_meta-v3.json = schemas\mod_meta-v3.json
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "structs", "structs", "{B03F276A-0572-4F62-AF86-EF62F6B80463}"
- ProjectSection(SolutionItems) = preProject
- schemas\structs\container.json = schemas\structs\container.json
- schemas\structs\group_combining.json = schemas\structs\group_combining.json
- schemas\structs\group_imc.json = schemas\structs\group_imc.json
- schemas\structs\group_multi.json = schemas\structs\group_multi.json
- schemas\structs\group_single.json = schemas\structs\group_single.json
- schemas\structs\manipulation.json = schemas\structs\manipulation.json
- schemas\structs\meta_atch.json = schemas\structs\meta_atch.json
- schemas\structs\meta_atr.json = schemas\structs\meta_atr.json
- schemas\structs\meta_enums.json = schemas\structs\meta_enums.json
- schemas\structs\meta_eqdp.json = schemas\structs\meta_eqdp.json
- schemas\structs\meta_eqp.json = schemas\structs\meta_eqp.json
- schemas\structs\meta_est.json = schemas\structs\meta_est.json
- schemas\structs\meta_geqp.json = schemas\structs\meta_geqp.json
- schemas\structs\meta_gmp.json = schemas\structs\meta_gmp.json
- schemas\structs\meta_imc.json = schemas\structs\meta_imc.json
- schemas\structs\meta_rsp.json = schemas\structs\meta_rsp.json
- schemas\structs\meta_shp.json = schemas\structs\meta_shp.json
- schemas\structs\option.json = schemas\structs\option.json
- EndProjectSection
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.PlayerWatch", "Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj", "{01685BD8-8847-4B49-BF90-1683B4C76B0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Release|x64 = Release|x64
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|x64.ActiveCfg = Debug|x64
- {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|x64.Build.0 = Debug|x64
- {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.ActiveCfg = Release|x64
- {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.Build.0 = Release|x64
- {EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|x64.ActiveCfg = Debug|x64
- {EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|x64.Build.0 = Debug|x64
- {EE551E87-FDB3-4612-B500-DC870C07C605}.Release|x64.ActiveCfg = Release|x64
- {EE551E87-FDB3-4612-B500-DC870C07C605}.Release|x64.Build.0 = Release|x64
- {87750518-1A20-40B4-9FC1-22F906EFB290}.Debug|x64.ActiveCfg = Debug|x64
- {87750518-1A20-40B4-9FC1-22F906EFB290}.Debug|x64.Build.0 = Debug|x64
- {87750518-1A20-40B4-9FC1-22F906EFB290}.Release|x64.ActiveCfg = Release|x64
- {87750518-1A20-40B4-9FC1-22F906EFB290}.Release|x64.Build.0 = Release|x64
- {1FE4D8DF-B56A-464F-B39E-CDC0ED4167D4}.Debug|x64.ActiveCfg = Debug|x64
- {1FE4D8DF-B56A-464F-B39E-CDC0ED4167D4}.Debug|x64.Build.0 = Debug|x64
- {1FE4D8DF-B56A-464F-B39E-CDC0ED4167D4}.Release|x64.ActiveCfg = Release|x64
- {1FE4D8DF-B56A-464F-B39E-CDC0ED4167D4}.Release|x64.Build.0 = Release|x64
- {5549BAFD-6357-4B1A-800C-75AC36E5B76D}.Debug|x64.ActiveCfg = Debug|x64
- {5549BAFD-6357-4B1A-800C-75AC36E5B76D}.Debug|x64.Build.0 = Debug|x64
- {5549BAFD-6357-4B1A-800C-75AC36E5B76D}.Release|x64.ActiveCfg = Release|x64
- {5549BAFD-6357-4B1A-800C-75AC36E5B76D}.Release|x64.Build.0 = Release|x64
- {EE834491-A98F-4395-BE0D-6861AE5AD953}.Debug|x64.ActiveCfg = Debug|x64
- {EE834491-A98F-4395-BE0D-6861AE5AD953}.Debug|x64.Build.0 = Debug|x64
- {EE834491-A98F-4395-BE0D-6861AE5AD953}.Release|x64.ActiveCfg = Release|x64
- {EE834491-A98F-4395-BE0D-6861AE5AD953}.Release|x64.Build.0 = Release|x64
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.Build.0 = Release|Any CPU
+ {01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {01685BD8-8847-4B49-BF90-1683B4C76B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {01685BD8-8847-4B49-BF90-1683B4C76B0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {BFEA7504-1210-4F79-A7FE-BF03B6567E33} = {F89C9EAE-25C8-43BE-8108-5921E5A93502}
- {B03F276A-0572-4F62-AF86-EF62F6B80463} = {BFEA7504-1210-4F79-A7FE-BF03B6567E33}
- EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B17E85B1-5F60-4440-9F9A-3DDE877E8CDF}
EndGlobalSection
diff --git a/Penumbra/API/ModsController.cs b/Penumbra/API/ModsController.cs
new file mode 100644
index 00000000..277f4a3a
--- /dev/null
+++ b/Penumbra/API/ModsController.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using System.Linq;
+using EmbedIO;
+using EmbedIO.Routing;
+using EmbedIO.WebApi;
+using Penumbra.Mods;
+using Penumbra.Util;
+
+namespace Penumbra.Api
+{
+ public class ModsController : WebApiController
+ {
+ private readonly Penumbra _penumbra;
+
+ public ModsController( Penumbra penumbra )
+ => _penumbra = penumbra;
+
+ [Route( HttpVerbs.Get, "/mods" )]
+ public object? GetMods()
+ {
+ var modManager = Service< ModManager >.Get();
+ return modManager.Collections.CurrentCollection.Cache?.AvailableMods.Values.Select( x => new
+ {
+ x.Settings.Enabled,
+ x.Settings.Priority,
+ x.Data.BasePath.Name,
+ x.Data.Meta,
+ BasePath = x.Data.BasePath.FullName,
+ Files = x.Data.Resources.ModFiles.Select( fi => fi.FullName ),
+ } )
+ ?? null;
+ }
+
+ [Route( HttpVerbs.Post, "/mods" )]
+ public object CreateMod()
+ => new { };
+
+ [Route( HttpVerbs.Get, "/files" )]
+ public object GetFiles()
+ {
+ var modManager = Service< ModManager >.Get();
+ return modManager.Collections.CurrentCollection.Cache?.ResolvedFiles.ToDictionary(
+ o => ( string )o.Key,
+ o => o.Value.FullName
+ )
+ ?? new Dictionary< string, string >();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Penumbra/Api/Api/ApiHelpers.cs b/Penumbra/Api/Api/ApiHelpers.cs
deleted file mode 100644
index 92a30bce..00000000
--- a/Penumbra/Api/Api/ApiHelpers.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using OtterGui.Log;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.GameData.Actors;
-using Penumbra.GameData.Interop;
-using Penumbra.Interop.PathResolving;
-
-namespace Penumbra.Api.Api;
-
-public class ApiHelpers(
- CollectionManager collectionManager,
- ObjectManager objects,
- CollectionResolver collectionResolver,
- ActorManager actors) : IApiService
-{
- /// Return the associated identifier for an object given by its index.
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- internal ActorIdentifier AssociatedIdentifier(int gameObjectIdx)
- {
- if (gameObjectIdx < 0 || gameObjectIdx >= objects.TotalCount)
- return ActorIdentifier.Invalid;
-
- var ptr = objects[gameObjectIdx];
- return actors.FromObject(ptr, out _, false, true, true);
- }
-
- ///
- /// Return the collection associated to a current game object. If it does not exist, return the default collection.
- /// If the index is invalid, returns false and the default collection.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- internal unsafe bool AssociatedCollection(int gameObjectIdx, out ModCollection collection)
- {
- collection = collectionManager.Active.Default;
- if (gameObjectIdx < 0 || gameObjectIdx >= objects.TotalCount)
- return false;
-
- var ptr = objects[gameObjectIdx];
- var data = collectionResolver.IdentifyCollection(ptr.AsObject, false);
- if (data.Valid)
- collection = data.ModCollection;
-
- return true;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- internal static PenumbraApiEc Return(PenumbraApiEc ec, LazyString args, [CallerMemberName] string name = "Unknown")
- {
- if (ec is PenumbraApiEc.Success or PenumbraApiEc.NothingChanged)
- Penumbra.Log.Verbose($"[{name}] Called with {args}, returned {ec}.");
- else
- Penumbra.Log.Debug($"[{name}] Called with {args}, returned {ec}.");
- return ec;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- internal static LazyString Args(params object[] arguments)
- {
- if (arguments.Length == 0)
- return new LazyString(() => "no arguments");
-
- return new LazyString(() =>
- {
- var sb = new StringBuilder();
- for (var i = 0; i < arguments.Length / 2; ++i)
- {
- sb.Append(arguments[2 * i]);
- sb.Append(" = ");
- sb.Append(arguments[2 * i + 1]);
- sb.Append(", ");
- }
-
- return sb.ToString(0, sb.Length - 2);
- });
- }
-}
diff --git a/Penumbra/Api/Api/CollectionApi.cs b/Penumbra/Api/Api/CollectionApi.cs
deleted file mode 100644
index c40feb12..00000000
--- a/Penumbra/Api/Api/CollectionApi.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.Mods;
-
-namespace Penumbra.Api.Api;
-
-public class CollectionApi(CollectionManager collections, ApiHelpers helpers) : IPenumbraApiCollection, IApiService
-{
- public Dictionary GetCollections()
- => collections.Storage.ToDictionary(c => c.Identity.Id, c => c.Identity.Name);
-
- public List<(Guid Id, string Name)> GetCollectionsByIdentifier(string identifier)
- {
- if (identifier.Length == 0)
- return [];
-
- var list = new List<(Guid Id, string Name)>(4);
- if (Guid.TryParse(identifier, out var guid) && collections.Storage.ById(guid, out var collection) && collection != ModCollection.Empty)
- list.Add((collection.Identity.Id, collection.Identity.Name));
- else if (identifier.Length >= 8)
- list.AddRange(collections.Storage.Where(c => c.Identity.Identifier.StartsWith(identifier, StringComparison.OrdinalIgnoreCase))
- .Select(c => (c.Identity.Id, c.Identity.Name)));
-
- list.AddRange(collections.Storage
- .Where(c => string.Equals(c.Identity.Name, identifier, StringComparison.OrdinalIgnoreCase)
- && !list.Contains((c.Identity.Id, c.Identity.Name)))
- .Select(c => (c.Identity.Id, c.Identity.Name)));
- return list;
- }
-
- public Func CheckCurrentChangedItemFunc()
- {
- var weakRef = new WeakReference(collections);
- return s =>
- {
- if (!weakRef.TryGetTarget(out var c))
- throw new ObjectDisposedException("The underlying collection storage of this IPC container was disposed.");
-
- if (!c.Active.Current.ChangedItems.TryGetValue(s, out var d))
- return [];
-
- return d.Item1.Select(m => (m is Mod mod ? mod.Identifier : string.Empty, m.Name.Text)).ToArray();
- };
- }
-
- public Dictionary GetChangedItemsForCollection(Guid collectionId)
- {
- try
- {
- if (!collections.Storage.ById(collectionId, out var collection))
- collection = ModCollection.Empty;
-
- if (collection.HasCache)
- return collection.ChangedItems.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Item2?.ToInternalObject());
-
- Penumbra.Log.Warning($"Collection {collectionId} does not exist or is not loaded.");
- return [];
- }
- catch (Exception e)
- {
- Penumbra.Log.Error($"Could not obtain Changed Items for {collectionId}:\n{e}");
- throw;
- }
- }
-
- public (Guid Id, string Name)? GetCollection(ApiCollectionType type)
- {
- if (!Enum.IsDefined(type))
- return null;
-
- var collection = collections.Active.ByType((CollectionType)type);
- return collection == null ? null : (collection.Identity.Id, collection.Identity.Name);
- }
-
- internal (Guid Id, string Name)? GetCollection(byte type)
- => GetCollection((ApiCollectionType)type);
-
- public (bool ObjectValid, bool IndividualSet, (Guid Id, string Name) EffectiveCollection) GetCollectionForObject(int gameObjectIdx)
- {
- var id = helpers.AssociatedIdentifier(gameObjectIdx);
- if (!id.IsValid)
- return (false, false, (collections.Active.Default.Identity.Id, collections.Active.Default.Identity.Name));
-
- if (collections.Active.Individuals.TryGetValue(id, out var collection))
- return (true, true, (collection.Identity.Id, collection.Identity.Name));
-
- helpers.AssociatedCollection(gameObjectIdx, out collection);
- return (true, false, (collection.Identity.Id, collection.Identity.Name));
- }
-
- public Guid[] GetCollectionByName(string name)
- => collections.Storage.Where(c => string.Equals(name, c.Identity.Name, StringComparison.OrdinalIgnoreCase)).Select(c => c.Identity.Id)
- .ToArray();
-
- public (PenumbraApiEc, (Guid Id, string Name)? OldCollection) SetCollection(ApiCollectionType type, Guid? collectionId,
- bool allowCreateNew, bool allowDelete)
- {
- if (!Enum.IsDefined(type))
- return (PenumbraApiEc.InvalidArgument, null);
-
- var oldCollection = collections.Active.ByType((CollectionType)type);
- var old = oldCollection != null ? (oldCollection.Identity.Id, oldCollection.Identity.Name) : new ValueTuple?();
- if (collectionId == null)
- {
- if (old == null)
- return (PenumbraApiEc.NothingChanged, old);
-
- if (!allowDelete || type is ApiCollectionType.Current or ApiCollectionType.Default or ApiCollectionType.Interface)
- return (PenumbraApiEc.AssignmentDeletionDisallowed, old);
-
- collections.Active.RemoveSpecialCollection((CollectionType)type);
- return (PenumbraApiEc.Success, old);
- }
-
- if (!collections.Storage.ById(collectionId.Value, out var collection))
- return (PenumbraApiEc.CollectionMissing, old);
-
- if (old == null)
- {
- if (!allowCreateNew)
- return (PenumbraApiEc.AssignmentCreationDisallowed, old);
-
- collections.Active.CreateSpecialCollection((CollectionType)type);
- }
- else if (old.Value.Item1 == collection.Identity.Id)
- {
- return (PenumbraApiEc.NothingChanged, old);
- }
-
- collections.Active.SetCollection(collection, (CollectionType)type);
- return (PenumbraApiEc.Success, old);
- }
-
- public (PenumbraApiEc, (Guid Id, string Name)? OldCollection) SetCollectionForObject(int gameObjectIdx, Guid? collectionId,
- bool allowCreateNew, bool allowDelete)
- {
- var id = helpers.AssociatedIdentifier(gameObjectIdx);
- if (!id.IsValid)
- return (PenumbraApiEc.InvalidIdentifier, (collections.Active.Default.Identity.Id, collections.Active.Default.Identity.Name));
-
- var oldCollection = collections.Active.Individuals.TryGetValue(id, out var c) ? c : null;
- var old = oldCollection != null ? (oldCollection.Identity.Id, oldCollection.Identity.Name) : new ValueTuple?();
- if (collectionId == null)
- {
- if (old == null)
- return (PenumbraApiEc.NothingChanged, old);
-
- if (!allowDelete)
- return (PenumbraApiEc.AssignmentDeletionDisallowed, old);
-
- var idx = collections.Active.Individuals.Index(id);
- collections.Active.RemoveIndividualCollection(idx);
- return (PenumbraApiEc.Success, old);
- }
-
- if (!collections.Storage.ById(collectionId.Value, out var collection))
- return (PenumbraApiEc.CollectionMissing, old);
-
- if (old == null)
- {
- if (!allowCreateNew)
- return (PenumbraApiEc.AssignmentCreationDisallowed, old);
-
- var ids = collections.Active.Individuals.GetGroup(id);
- collections.Active.CreateIndividualCollection(ids);
- }
- else if (old.Value.Item1 == collection.Identity.Id)
- {
- return (PenumbraApiEc.NothingChanged, old);
- }
-
- collections.Active.SetCollection(collection, CollectionType.Individual, collections.Active.Individuals.Index(id));
- return (PenumbraApiEc.Success, old);
- }
-}
diff --git a/Penumbra/Api/Api/EditingApi.cs b/Penumbra/Api/Api/EditingApi.cs
deleted file mode 100644
index 5a1fc347..00000000
--- a/Penumbra/Api/Api/EditingApi.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using OtterGui.Services;
-using Penumbra.Import.Textures;
-using TextureType = Penumbra.Api.Enums.TextureType;
-
-namespace Penumbra.Api.Api;
-
-public class EditingApi(TextureManager textureManager) : IPenumbraApiEditing, IApiService
-{
- public Task ConvertTextureFile(string inputFile, string outputFile, TextureType textureType, bool mipMaps)
- => textureType switch
- {
- TextureType.Png => textureManager.SavePng(inputFile, outputFile),
- TextureType.Targa => textureManager.SaveTga(inputFile, outputFile),
- TextureType.AsIsTex => textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, true, inputFile, outputFile),
- TextureType.AsIsDds => textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, false, inputFile, outputFile),
- TextureType.RgbaTex => textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, true, inputFile, outputFile),
- TextureType.RgbaDds => textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, false, inputFile, outputFile),
- TextureType.Bc3Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, true, inputFile, outputFile),
- TextureType.Bc3Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, false, inputFile, outputFile),
- TextureType.Bc7Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, true, inputFile, outputFile),
- TextureType.Bc7Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, false, inputFile, outputFile),
- TextureType.Bc1Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC1, mipMaps, true, inputFile, outputFile),
- TextureType.Bc1Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC1, mipMaps, false, inputFile, outputFile),
- TextureType.Bc4Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC4, mipMaps, true, inputFile, outputFile),
- TextureType.Bc4Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC4, mipMaps, false, inputFile, outputFile),
- TextureType.Bc5Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC5, mipMaps, true, inputFile, outputFile),
- TextureType.Bc5Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC5, mipMaps, false, inputFile, outputFile),
- _ => Task.FromException(new Exception($"Invalid input value {textureType}.")),
- };
-
- // @formatter:off
- public Task ConvertTextureData(byte[] rgbaData, int width, string outputFile, TextureType textureType, bool mipMaps)
- => textureType switch
- {
- TextureType.Png => textureManager.SavePng(new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Targa => textureManager.SaveTga(new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.AsIsTex => textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.AsIsDds => textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.RgbaTex => textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.RgbaDds => textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc3Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc3Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc7Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc7Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc1Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC1, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc1Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC1, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc4Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC4, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc4Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC4, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc5Tex => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC5, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- TextureType.Bc5Dds => textureManager.SaveAs(CombinedTexture.TextureSaveType.BC5, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
- _ => Task.FromException(new Exception($"Invalid input value {textureType}.")),
- };
- // @formatter:on
-}
diff --git a/Penumbra/Api/Api/GameStateApi.cs b/Penumbra/Api/Api/GameStateApi.cs
deleted file mode 100644
index 74cde3a0..00000000
--- a/Penumbra/Api/Api/GameStateApi.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Collections;
-using Penumbra.Interop.Hooks.ResourceLoading;
-using Penumbra.Interop.PathResolving;
-using Penumbra.Interop.Structs;
-using Penumbra.Services;
-using Penumbra.String.Classes;
-
-namespace Penumbra.Api.Api;
-
-public class GameStateApi : IPenumbraApiGameState, IApiService, IDisposable
-{
- private readonly CommunicatorService _communicator;
- private readonly CollectionResolver _collectionResolver;
- private readonly DrawObjectState _drawObjectState;
- private readonly CutsceneService _cutsceneService;
- private readonly ResourceLoader _resourceLoader;
-
- public unsafe GameStateApi(CommunicatorService communicator, CollectionResolver collectionResolver, CutsceneService cutsceneService,
- ResourceLoader resourceLoader, DrawObjectState drawObjectState)
- {
- _communicator = communicator;
- _collectionResolver = collectionResolver;
- _cutsceneService = cutsceneService;
- _resourceLoader = resourceLoader;
- _drawObjectState = drawObjectState;
- _resourceLoader.ResourceLoaded += OnResourceLoaded;
- _resourceLoader.PapRequested += OnPapRequested;
- _communicator.CreatedCharacterBase.Subscribe(OnCreatedCharacterBase, Communication.CreatedCharacterBase.Priority.Api);
- }
-
- public unsafe void Dispose()
- {
- _resourceLoader.ResourceLoaded -= OnResourceLoaded;
- _resourceLoader.PapRequested -= OnPapRequested;
- _communicator.CreatedCharacterBase.Unsubscribe(OnCreatedCharacterBase);
- }
-
- public event CreatedCharacterBaseDelegate? CreatedCharacterBase;
- public event GameObjectResourceResolvedDelegate? GameObjectResourceResolved;
-
- public event CreatingCharacterBaseDelegate? CreatingCharacterBase
- {
- add
- {
- if (value == null)
- return;
-
- _communicator.CreatingCharacterBase.Subscribe(new Action(value),
- Communication.CreatingCharacterBase.Priority.Api);
- }
- remove
- {
- if (value == null)
- return;
-
- _communicator.CreatingCharacterBase.Unsubscribe(new Action(value));
- }
- }
-
- public unsafe (nint GameObject, (Guid Id, string Name) Collection) GetDrawObjectInfo(nint drawObject)
- {
- var data = _collectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
- return (data.AssociatedGameObject, (Id: data.ModCollection.Identity.Id, Name: data.ModCollection.Identity.Name));
- }
-
- public int GetCutsceneParentIndex(int actorIdx)
- => _cutsceneService.GetParentIndex(actorIdx);
-
- public Func GetCutsceneParentIndexFunc()
- {
- var weakRef = new WeakReference(_cutsceneService);
- return idx =>
- {
- if (!weakRef.TryGetTarget(out var c))
- throw new ObjectDisposedException("The underlying cutscene state storage of this IPC container was disposed.");
-
- return c.GetParentIndex(idx);
- };
- }
-
- public Func GetGameObjectFromDrawObjectFunc()
- {
- var weakRef = new WeakReference(_drawObjectState);
- return model =>
- {
- if (!weakRef.TryGetTarget(out var c))
- throw new ObjectDisposedException("The underlying draw object state storage of this IPC container was disposed.");
-
- return c.TryGetValue(model, out var data) ? data.Item1.Address : nint.Zero;
- };
- }
-
- public PenumbraApiEc SetCutsceneParentIndex(int copyIdx, int newParentIdx)
- => _cutsceneService.SetParentIndex(copyIdx, newParentIdx)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.InvalidArgument;
-
- private unsafe void OnResourceLoaded(ResourceHandle* handle, Utf8GamePath originalPath, FullPath? manipulatedPath, ResolveData resolveData)
- {
- if (resolveData.AssociatedGameObject != nint.Zero && GameObjectResourceResolved != null)
- {
- var original = originalPath.ToString();
- GameObjectResourceResolved.Invoke(resolveData.AssociatedGameObject, original,
- manipulatedPath?.ToString() ?? original);
- }
- }
-
- private void OnPapRequested(Utf8GamePath originalPath, FullPath? manipulatedPath, ResolveData resolveData)
- {
- if (resolveData.AssociatedGameObject != nint.Zero && GameObjectResourceResolved != null)
- {
- var original = originalPath.ToString();
- GameObjectResourceResolved.Invoke(resolveData.AssociatedGameObject, original,
- manipulatedPath?.ToString() ?? original);
- }
- }
-
- private void OnCreatedCharacterBase(nint gameObject, ModCollection collection, nint drawObject)
- => CreatedCharacterBase?.Invoke(gameObject, collection.Identity.Id, drawObject);
-}
diff --git a/Penumbra/Api/Api/IdentityChecker.cs b/Penumbra/Api/Api/IdentityChecker.cs
deleted file mode 100644
index e090053e..00000000
--- a/Penumbra/Api/Api/IdentityChecker.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Penumbra.Api.Api;
-
-public static class IdentityChecker
-{
- public static bool Check(string identity)
- => true;
-}
diff --git a/Penumbra/Api/Api/MetaApi.cs b/Penumbra/Api/Api/MetaApi.cs
deleted file mode 100644
index 5cffc811..00000000
--- a/Penumbra/Api/Api/MetaApi.cs
+++ /dev/null
@@ -1,544 +0,0 @@
-using Dalamud.Plugin.Services;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using OtterGui;
-using OtterGui.Services;
-using Penumbra.Collections;
-using Penumbra.Collections.Cache;
-using Penumbra.GameData.Files.AtchStructs;
-using Penumbra.GameData.Files.Utility;
-using Penumbra.GameData.Structs;
-using Penumbra.Interop.PathResolving;
-using Penumbra.Meta.Manipulations;
-
-namespace Penumbra.Api.Api;
-
-public class MetaApi(IFramework framework, CollectionResolver collectionResolver, ApiHelpers helpers)
- : IPenumbraApiMeta, IApiService
-{
- public string GetPlayerMetaManipulations()
- {
- var collection = collectionResolver.PlayerCollection();
- return CompressMetaManipulations(collection);
- }
-
- public string GetMetaManipulations(int gameObjectIdx)
- {
- helpers.AssociatedCollection(gameObjectIdx, out var collection);
- return CompressMetaManipulations(collection);
- }
-
- public Task GetPlayerMetaManipulationsAsync()
- {
- return Task.Run(async () =>
- {
- var playerCollection = await framework.RunOnFrameworkThread(collectionResolver.PlayerCollection).ConfigureAwait(false);
- return CompressMetaManipulations(playerCollection);
- });
- }
-
- public Task GetMetaManipulationsAsync(int gameObjectIdx)
- {
- return Task.Run(async () =>
- {
- var playerCollection = await framework.RunOnFrameworkThread(() =>
- {
- helpers.AssociatedCollection(gameObjectIdx, out var collection);
- return collection;
- }).ConfigureAwait(false);
- return CompressMetaManipulations(playerCollection);
- });
- }
-
- internal static string CompressMetaManipulations(ModCollection collection)
- => CompressMetaManipulationsV1(collection);
-
- private static string CompressMetaManipulationsV0(ModCollection collection)
- {
- var array = new JArray();
- if (collection.MetaCache is { } cache)
- {
- MetaDictionary.SerializeTo(array, cache.GlobalEqp.Select(kvp => kvp.Key));
- MetaDictionary.SerializeTo(array, cache.Imc.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Eqp.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Eqdp.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Est.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Rsp.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Gmp.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Atch.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Shp.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- MetaDictionary.SerializeTo(array, cache.Atr.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.Entry)));
- }
-
- return Functions.ToCompressedBase64(array, 0);
- }
-
- private static unsafe string CompressMetaManipulationsV1(ModCollection? collection)
- {
- using var ms = new MemoryStream();
- ms.Capacity = 1024;
- using (var zipStream = new GZipStream(ms, CompressionMode.Compress, true))
- {
- zipStream.Write((byte)1);
- zipStream.Write("META0001"u8);
- if (collection?.MetaCache is not { } cache)
- {
- zipStream.Write(0);
- zipStream.Write(0);
- zipStream.Write(0);
- zipStream.Write(0);
- zipStream.Write(0);
- zipStream.Write(0);
- zipStream.Write(0);
- }
- else
- {
- WriteCache(zipStream, cache.Imc);
- WriteCache(zipStream, cache.Eqp);
- WriteCache(zipStream, cache.Eqdp);
- WriteCache(zipStream, cache.Est);
- WriteCache(zipStream, cache.Rsp);
- WriteCache(zipStream, cache.Gmp);
- cache.GlobalEqp.EnterReadLock();
-
- try
- {
- zipStream.Write(cache.GlobalEqp.Count);
- foreach (var (globalEqp, _) in cache.GlobalEqp)
- zipStream.Write(new ReadOnlySpan(&globalEqp, sizeof(GlobalEqpManipulation)));
- }
- finally
- {
- cache.GlobalEqp.ExitReadLock();
- }
-
- WriteCache(zipStream, cache.Atch);
- WriteCache(zipStream, cache.Shp);
- WriteCache(zipStream, cache.Atr);
- }
- }
-
- ms.Flush();
- ms.Position = 0;
- var data = ms.GetBuffer().AsSpan(0, (int)ms.Length);
- return Convert.ToBase64String(data);
-
- void WriteCache(Stream stream, MetaCacheBase metaCache)
- where TKey : unmanaged, IMetaIdentifier
- where TValue : unmanaged
- {
- metaCache.EnterReadLock();
- try
- {
- stream.Write(metaCache.Count);
- foreach (var (identifier, (_, value)) in metaCache)
- {
- stream.Write(identifier);
- stream.Write(value);
- }
- }
- finally
- {
- metaCache.ExitReadLock();
- }
- }
- }
-
- public const uint ImcKey = ((uint)'I' << 24) | ((uint)'M' << 16) | ((uint)'C' << 8);
- public const uint EqpKey = ((uint)'E' << 24) | ((uint)'Q' << 16) | ((uint)'P' << 8);
- public const uint EqdpKey = ((uint)'E' << 24) | ((uint)'Q' << 16) | ((uint)'D' << 8) | 'P';
- public const uint EstKey = ((uint)'E' << 24) | ((uint)'S' << 16) | ((uint)'T' << 8);
- public const uint RspKey = ((uint)'R' << 24) | ((uint)'S' << 16) | ((uint)'P' << 8);
- public const uint GmpKey = ((uint)'G' << 24) | ((uint)'M' << 16) | ((uint)'P' << 8);
- public const uint GeqpKey = ((uint)'G' << 24) | ((uint)'E' << 16) | ((uint)'Q' << 8) | 'P';
- public const uint AtchKey = ((uint)'A' << 24) | ((uint)'T' << 16) | ((uint)'C' << 8) | 'H';
- public const uint ShpKey = ((uint)'S' << 24) | ((uint)'H' << 16) | ((uint)'P' << 8);
- public const uint AtrKey = ((uint)'A' << 24) | ((uint)'T' << 16) | ((uint)'R' << 8);
-
- private static unsafe string CompressMetaManipulationsV2(ModCollection? collection)
- {
- using var ms = new MemoryStream();
- ms.Capacity = 1024;
- using (var zipStream = new GZipStream(ms, CompressionMode.Compress, true))
- {
- zipStream.Write((byte)2);
- zipStream.Write("META0002"u8);
- if (collection?.MetaCache is { } cache)
- {
- WriteCache(zipStream, cache.Imc, ImcKey);
- WriteCache(zipStream, cache.Eqp, EqpKey);
- WriteCache(zipStream, cache.Eqdp, EqdpKey);
- WriteCache(zipStream, cache.Est, EstKey);
- WriteCache(zipStream, cache.Rsp, RspKey);
- WriteCache(zipStream, cache.Gmp, GmpKey);
- cache.GlobalEqp.EnterReadLock();
-
- try
- {
- if (cache.GlobalEqp.Count > 0)
- {
- zipStream.Write(GeqpKey);
- zipStream.Write(cache.GlobalEqp.Count);
- foreach (var (globalEqp, _) in cache.GlobalEqp)
- zipStream.Write(new ReadOnlySpan(&globalEqp, sizeof(GlobalEqpManipulation)));
- }
- }
- finally
- {
- cache.GlobalEqp.ExitReadLock();
- }
-
- WriteCache(zipStream, cache.Atch, AtchKey);
- WriteCache(zipStream, cache.Shp, ShpKey);
- WriteCache(zipStream, cache.Atr, AtrKey);
- }
- }
-
- ms.Flush();
- ms.Position = 0;
- var data = ms.GetBuffer().AsSpan(0, (int)ms.Length);
- return Convert.ToBase64String(data);
-
- void WriteCache(Stream stream, MetaCacheBase metaCache, uint label)
- where TKey : unmanaged, IMetaIdentifier
- where TValue : unmanaged
- {
- metaCache.EnterReadLock();
- try
- {
- if (metaCache.Count <= 0)
- return;
-
- stream.Write(label);
- stream.Write(metaCache.Count);
- foreach (var (identifier, (_, value)) in metaCache)
- {
- stream.Write(identifier);
- stream.Write(value);
- }
- }
- finally
- {
- metaCache.ExitReadLock();
- }
- }
- }
-
- ///
- /// Convert manipulations from a transmitted base64 string to actual manipulations.
- /// The empty string is treated as an empty set.
- /// Only returns true if all conversions are successful and distinct.
- ///
- internal static bool ConvertManips(string manipString, [NotNullWhen(true)] out MetaDictionary? manips, out byte version)
- {
- if (manipString.Length == 0)
- {
- manips = new MetaDictionary();
- version = byte.MaxValue;
- return true;
- }
-
- try
- {
- var bytes = Convert.FromBase64String(manipString);
- using var compressedStream = new MemoryStream(bytes);
- using var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress);
- using var resultStream = new MemoryStream();
- zipStream.CopyTo(resultStream);
- resultStream.Flush();
- resultStream.Position = 0;
- var data = resultStream.GetBuffer().AsSpan(0, (int)resultStream.Length);
- version = data[0];
- data = data[1..];
- switch (version)
- {
- case 0: return ConvertManipsV0(data, out manips);
- case 1: return ConvertManipsV1(data, out manips);
- case 2: return ConvertManipsV2(data, out manips);
- default:
- Penumbra.Log.Debug($"Invalid version for manipulations: {version}.");
- manips = null;
- return false;
- }
- }
- catch (Exception ex)
- {
- Penumbra.Log.Debug($"Error decompressing manipulations:\n{ex}");
- manips = null;
- version = byte.MaxValue;
- return false;
- }
- }
-
- private static bool ConvertManipsV2(ReadOnlySpan data, [NotNullWhen(true)] out MetaDictionary? manips)
- {
- if (!data.StartsWith("META0002"u8))
- {
- Penumbra.Log.Debug("Invalid manipulations of version 2, does not start with valid prefix.");
- manips = null;
- return false;
- }
-
- manips = new MetaDictionary();
- var r = new SpanBinaryReader(data[8..]);
- while (r.Remaining > 4)
- {
- var prefix = r.ReadUInt32();
- var count = r.Remaining > 4 ? r.ReadInt32() : 0;
- if (count is 0)
- continue;
-
- switch (prefix)
- {
- case ImcKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case EqpKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case EqdpKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case EstKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case RspKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case GmpKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case GeqpKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier))
- return false;
- }
-
- break;
- case AtchKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case ShpKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- case AtrKey:
- for (var i = 0; i < count; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- break;
- }
- }
-
- return true;
- }
-
- private static bool ConvertManipsV1(ReadOnlySpan data, [NotNullWhen(true)] out MetaDictionary? manips)
- {
- if (!data.StartsWith("META0001"u8))
- {
- Penumbra.Log.Debug($"Invalid manipulations of version 1, does not start with valid prefix.");
- manips = null;
- return false;
- }
-
- manips = new MetaDictionary();
- var r = new SpanBinaryReader(data[8..]);
- var imcCount = r.ReadInt32();
- for (var i = 0; i < imcCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var eqpCount = r.ReadInt32();
- for (var i = 0; i < eqpCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var eqdpCount = r.ReadInt32();
- for (var i = 0; i < eqdpCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var estCount = r.ReadInt32();
- for (var i = 0; i < estCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var rspCount = r.ReadInt32();
- for (var i = 0; i < rspCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var gmpCount = r.ReadInt32();
- for (var i = 0; i < gmpCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var globalEqpCount = r.ReadInt32();
- for (var i = 0; i < globalEqpCount; ++i)
- {
- var manip = r.Read();
- if (!manip.Validate() || !manips.TryAdd(manip))
- return false;
- }
-
- // Atch was added after there were already some V1 around, so check for size here.
- if (r.Position < r.Count)
- {
- var atchCount = r.ReadInt32();
- for (var i = 0; i < atchCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- // Shp and Atr was added later
- if (r.Position < r.Count)
- {
- var shpCount = r.ReadInt32();
- for (var i = 0; i < shpCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
-
- var atrCount = r.ReadInt32();
- for (var i = 0; i < atrCount; ++i)
- {
- var identifier = r.Read();
- var value = r.Read();
- if (!identifier.Validate() || !manips.TryAdd(identifier, value))
- return false;
- }
- }
- }
-
- return true;
- }
-
- private static bool ConvertManipsV0(ReadOnlySpan data, [NotNullWhen(true)] out MetaDictionary? manips)
- {
- var json = Encoding.UTF8.GetString(data);
- manips = JsonConvert.DeserializeObject(json);
- return manips != null;
- }
-
- internal void TestMetaManipulations()
- {
- var collection = collectionResolver.PlayerCollection();
- var dict = new MetaDictionary(collection.MetaCache);
- var count = dict.Count;
-
- var watch = Stopwatch.StartNew();
- var v0 = CompressMetaManipulationsV0(collection);
- var v0Time = watch.ElapsedMilliseconds;
-
- watch.Restart();
- var v1 = CompressMetaManipulationsV1(collection);
- var v1Time = watch.ElapsedMilliseconds;
-
- watch.Restart();
- var v1Success = ConvertManips(v1, out var v1Roundtrip, out _);
- var v1RoundtripTime = watch.ElapsedMilliseconds;
-
- watch.Restart();
- var v0Success = ConvertManips(v0, out var v0Roundtrip, out _);
- var v0RoundtripTime = watch.ElapsedMilliseconds;
-
- Penumbra.Log.Information($"Version | Count | Time | Length | Success | ReCount | ReTime | Equal");
- Penumbra.Log.Information(
- $"0 | {count} | {v0Time} | {v0.Length} | {v0Success} | {v0Roundtrip?.Count} | {v0RoundtripTime} | {v0Roundtrip?.Equals(dict)}");
- Penumbra.Log.Information(
- $"1 | {count} | {v1Time} | {v1.Length} | {v1Success} | {v1Roundtrip?.Count} | {v1RoundtripTime} | {v0Roundtrip?.Equals(dict)}");
- }
-}
diff --git a/Penumbra/Api/Api/ModSettingsApi.cs b/Penumbra/Api/Api/ModSettingsApi.cs
deleted file mode 100644
index d49c2904..00000000
--- a/Penumbra/Api/Api/ModSettingsApi.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-using OtterGui.Extensions;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.Communication;
-using Penumbra.Interop.PathResolving;
-using Penumbra.Mods;
-using Penumbra.Mods.Editor;
-using Penumbra.Mods.Groups;
-using Penumbra.Mods.Manager;
-using Penumbra.Mods.Manager.OptionEditor;
-using Penumbra.Mods.Settings;
-using Penumbra.Mods.SubMods;
-using Penumbra.Services;
-
-namespace Penumbra.Api.Api;
-
-public class ModSettingsApi : IPenumbraApiModSettings, IApiService, IDisposable
-{
- private readonly CollectionResolver _collectionResolver;
- private readonly ModManager _modManager;
- private readonly CollectionManager _collectionManager;
- private readonly CollectionEditor _collectionEditor;
- private readonly CommunicatorService _communicator;
-
- public ModSettingsApi(CollectionResolver collectionResolver,
- ModManager modManager,
- CollectionManager collectionManager,
- CollectionEditor collectionEditor,
- CommunicatorService communicator)
- {
- _collectionResolver = collectionResolver;
- _modManager = modManager;
- _collectionManager = collectionManager;
- _collectionEditor = collectionEditor;
- _communicator = communicator;
- _communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ApiModSettings);
- _communicator.ModSettingChanged.Subscribe(OnModSettingChange, Communication.ModSettingChanged.Priority.Api);
- _communicator.ModOptionChanged.Subscribe(OnModOptionEdited, ModOptionChanged.Priority.Api);
- _communicator.ModFileChanged.Subscribe(OnModFileChanged, ModFileChanged.Priority.Api);
- }
-
- public void Dispose()
- {
- _communicator.ModPathChanged.Unsubscribe(OnModPathChange);
- _communicator.ModSettingChanged.Unsubscribe(OnModSettingChange);
- _communicator.ModOptionChanged.Unsubscribe(OnModOptionEdited);
- _communicator.ModFileChanged.Unsubscribe(OnModFileChanged);
- }
-
- public event ModSettingChangedDelegate? ModSettingChanged;
-
- public AvailableModSettings? GetAvailableModSettings(string modDirectory, string modName)
- {
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return null;
-
- var dict = new Dictionary(mod.Groups.Count);
- foreach (var g in mod.Groups)
- dict.Add(g.Name, (g.Options.Select(o => o.Name).ToArray(), (int)g.Type));
- return new AvailableModSettings(dict);
- }
-
- public (PenumbraApiEc, (bool, int, Dictionary>, bool)?) GetCurrentModSettings(Guid collectionId, string modDirectory,
- string modName, bool ignoreInheritance)
- {
- var ret = GetCurrentModSettingsWithTemp(collectionId, modDirectory, modName, ignoreInheritance, true, 0);
- if (ret.Item2 is null)
- return (ret.Item1, null);
-
- return (ret.Item1, (ret.Item2.Value.Item1, ret.Item2.Value.Item2, ret.Item2.Value.Item3, ret.Item2.Value.Item4));
- }
-
- public PenumbraApiEc GetSettingsInAllCollections(string modDirectory, string modName,
- out Dictionary>, bool, bool)> settings,
- bool ignoreTemporaryCollections = false)
- {
- settings = [];
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return PenumbraApiEc.ModMissing;
-
- var collections = ignoreTemporaryCollections
- ? _collectionManager.Storage.Where(c => c != ModCollection.Empty)
- : _collectionManager.Storage.Where(c => c != ModCollection.Empty).Concat(_collectionManager.Temp.Values);
- settings = [];
- foreach (var collection in collections)
- {
- if (GetCurrentSettings(collection, mod, false, false, 0) is { } s)
- settings.Add(collection.Identity.Id, s);
- }
-
- return PenumbraApiEc.Success;
- }
-
- public (PenumbraApiEc, (bool, int, Dictionary>, bool, bool)?) GetCurrentModSettingsWithTemp(Guid collectionId,
- string modDirectory, string modName, bool ignoreInheritance, bool ignoreTemporary, int key)
- {
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return (PenumbraApiEc.ModMissing, null);
-
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return (PenumbraApiEc.CollectionMissing, null);
-
- if (collection.Identity.Id == Guid.Empty)
- return (PenumbraApiEc.Success, null);
-
- if (GetCurrentSettings(collection, mod, ignoreInheritance, ignoreTemporary, key) is { } settings)
- return (PenumbraApiEc.Success, settings);
-
- return (PenumbraApiEc.Success, null);
- }
-
- public (PenumbraApiEc, Dictionary>, bool, bool)>?) GetAllModSettings(Guid collectionId,
- bool ignoreInheritance, bool ignoreTemporary, int key)
- {
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return (PenumbraApiEc.CollectionMissing, null);
-
- if (collection.Identity.Id == Guid.Empty)
- return (PenumbraApiEc.Success, []);
-
- var ret = new Dictionary>, bool, bool)>(_modManager.Count);
- foreach (var mod in _modManager)
- {
- if (GetCurrentSettings(collection, mod, ignoreInheritance, ignoreTemporary, key) is { } settings)
- ret[mod.Identifier] = settings;
- }
-
- return (PenumbraApiEc.Success, ret);
- }
-
- public PenumbraApiEc TryInheritMod(Guid collectionId, string modDirectory, string modName, bool inherit)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "Inherit",
- inherit.ToString());
-
- if (collectionId == Guid.Empty)
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- var ret = _collectionEditor.SetModInheritance(collection, mod, inherit)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.NothingChanged;
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc TrySetMod(Guid collectionId, string modDirectory, string modName, bool enabled)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "Enabled", enabled);
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- var ret = _collectionEditor.SetModState(collection, mod, enabled)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.NothingChanged;
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc TrySetModPriority(Guid collectionId, string modDirectory, string modName, int priority)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "Priority", priority);
-
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- var ret = _collectionEditor.SetModPriority(collection, mod, new ModPriority(priority))
- ? PenumbraApiEc.Success
- : PenumbraApiEc.NothingChanged;
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc TrySetModSetting(Guid collectionId, string modDirectory, string modName, string optionGroupName, string optionName)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "OptionGroupName",
- optionGroupName, "OptionName", optionName);
-
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- var groupIdx = mod.Groups.IndexOf(g => g.Name == optionGroupName);
- if (groupIdx < 0)
- return ApiHelpers.Return(PenumbraApiEc.OptionGroupMissing, args);
-
- var optionIdx = mod.Groups[groupIdx].Options.IndexOf(o => o.Name == optionName);
- if (optionIdx < 0)
- return ApiHelpers.Return(PenumbraApiEc.OptionMissing, args);
-
- var setting = mod.Groups[groupIdx].Behaviour switch
- {
- GroupDrawBehaviour.MultiSelection => Setting.Multi(optionIdx),
- GroupDrawBehaviour.SingleSelection => Setting.Single(optionIdx),
- _ => Setting.Zero,
- };
- var ret = _collectionEditor.SetModSetting(collection, mod, groupIdx, setting)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.NothingChanged;
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc TrySetModSettings(Guid collectionId, string modDirectory, string modName, string optionGroupName,
- IReadOnlyList optionNames)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "OptionGroupName",
- optionGroupName, "#optionNames", optionNames.Count);
-
- if (!_collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- var settingSuccess = ConvertModSetting(mod, optionGroupName, optionNames, out var groupIdx, out var setting);
- if (settingSuccess is not PenumbraApiEc.Success)
- return ApiHelpers.Return(settingSuccess, args);
-
- var ret = _collectionEditor.SetModSetting(collection, mod, groupIdx, setting)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.NothingChanged;
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc CopyModSettings(Guid? collectionId, string modDirectoryFrom, string modDirectoryTo)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId.HasValue ? collectionId.Value.ToString() : "NULL",
- "From", modDirectoryFrom, "To", modDirectoryTo);
- var sourceMod = _modManager.FirstOrDefault(m => string.Equals(m.ModPath.Name, modDirectoryFrom, StringComparison.OrdinalIgnoreCase));
- var targetMod = _modManager.FirstOrDefault(m => string.Equals(m.ModPath.Name, modDirectoryTo, StringComparison.OrdinalIgnoreCase));
- if (collectionId == null)
- foreach (var collection in _collectionManager.Storage)
- _collectionEditor.CopyModSettings(collection, sourceMod, modDirectoryFrom, targetMod, modDirectoryTo);
- else if (_collectionManager.Storage.ById(collectionId.Value, out var collection))
- _collectionEditor.CopyModSettings(collection, sourceMod, modDirectoryFrom, targetMod, modDirectoryTo);
- else
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- return ApiHelpers.Return(PenumbraApiEc.Success, args);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- private (bool, int, Dictionary>, bool, bool)? GetCurrentSettings(ModCollection collection, Mod mod,
- bool ignoreInheritance, bool ignoreTemporary, int key)
- {
- var settings = collection.Settings.Settings[mod.Index];
- if (!ignoreTemporary && settings.TempSettings is { } tempSettings && (tempSettings.Lock <= 0 || tempSettings.Lock == key))
- {
- if (!tempSettings.ForceInherit)
- return (tempSettings.Enabled, tempSettings.Priority.Value, tempSettings.ConvertToShareable(mod).Settings,
- false, true);
- if (!ignoreInheritance && collection.GetActualSettings(mod.Index).Settings is { } actualSettingsTemp)
- return (actualSettingsTemp.Enabled, actualSettingsTemp.Priority.Value,
- actualSettingsTemp.ConvertToShareable(mod).Settings, true, true);
- }
-
- if (settings.Settings is { } ownSettings)
- return (ownSettings.Enabled, ownSettings.Priority.Value, ownSettings.ConvertToShareable(mod).Settings, false,
- false);
- if (!ignoreInheritance && collection.GetInheritedSettings(mod.Index).Settings is { } actualSettings)
- return (actualSettings.Enabled, actualSettings.Priority.Value,
- actualSettings.ConvertToShareable(mod).Settings, true, false);
-
- return null;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- private void TriggerSettingEdited(Mod mod)
- {
- var collection = _collectionResolver.PlayerCollection();
- var (settings, parent) = collection.GetActualSettings(mod.Index);
- if (settings is { Enabled: true })
- ModSettingChanged?.Invoke(ModSettingChange.Edited, collection.Identity.Id, mod.Identifier, parent != collection);
- }
-
- private void OnModPathChange(ModPathChangeType type, Mod mod, DirectoryInfo? _1, DirectoryInfo? _2)
- {
- if (type == ModPathChangeType.Reloaded)
- TriggerSettingEdited(mod);
- }
-
- private void OnModSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, Setting _1, int _2, bool inherited)
- => ModSettingChanged?.Invoke(type, collection.Identity.Id, mod?.ModPath.Name ?? string.Empty, inherited);
-
- private void OnModOptionEdited(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container,
- int moveIndex)
- {
- switch (type)
- {
- case ModOptionChangeType.GroupDeleted:
- case ModOptionChangeType.GroupMoved:
- case ModOptionChangeType.GroupTypeChanged:
- case ModOptionChangeType.PriorityChanged:
- case ModOptionChangeType.OptionDeleted:
- case ModOptionChangeType.OptionMoved:
- case ModOptionChangeType.OptionFilesChanged:
- case ModOptionChangeType.OptionFilesAdded:
- case ModOptionChangeType.OptionSwapsChanged:
- case ModOptionChangeType.OptionMetaChanged:
- TriggerSettingEdited(mod);
- break;
- }
- }
-
- private void OnModFileChanged(Mod mod, FileRegistry file)
- {
- if (file.CurrentUsage == 0)
- return;
-
- TriggerSettingEdited(mod);
- }
-
- public static PenumbraApiEc ConvertModSetting(Mod mod, string groupName, IReadOnlyList optionNames, out int groupIndex,
- out Setting setting)
- {
- groupIndex = mod.Groups.IndexOf(g => g.Name.Equals(groupName, StringComparison.OrdinalIgnoreCase));
- setting = Setting.Zero;
- if (groupIndex < 0)
- return PenumbraApiEc.OptionGroupMissing;
-
- switch (mod.Groups[groupIndex])
- {
- case { Behaviour: GroupDrawBehaviour.SingleSelection } single:
- {
- var optionIdx = optionNames.Count == 0 ? -1 : single.Options.IndexOf(o => o.Name == optionNames[^1]);
- if (optionIdx < 0)
- return PenumbraApiEc.OptionMissing;
-
- setting = Setting.Single(optionIdx);
- break;
- }
- case { Behaviour: GroupDrawBehaviour.MultiSelection } multi:
- {
- foreach (var name in optionNames)
- {
- var optionIdx = multi.Options.IndexOf(o => o.Name == name);
- if (optionIdx < 0)
- return PenumbraApiEc.OptionMissing;
-
- setting |= Setting.Multi(optionIdx);
- }
-
- break;
- }
- }
-
- return PenumbraApiEc.Success;
- }
-}
diff --git a/Penumbra/Api/Api/ModsApi.cs b/Penumbra/Api/Api/ModsApi.cs
deleted file mode 100644
index 1f4f1cf4..00000000
--- a/Penumbra/Api/Api/ModsApi.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-using Newtonsoft.Json.Linq;
-using OtterGui.Compression;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Communication;
-using Penumbra.Mods;
-using Penumbra.Mods.Manager;
-using Penumbra.Services;
-
-namespace Penumbra.Api.Api;
-
-public class ModsApi : IPenumbraApiMods, IApiService, IDisposable
-{
- private readonly CommunicatorService _communicator;
- private readonly ModManager _modManager;
- private readonly ModImportManager _modImportManager;
- private readonly Configuration _config;
- private readonly ModFileSystem _modFileSystem;
- private readonly MigrationManager _migrationManager;
-
- public ModsApi(ModManager modManager, ModImportManager modImportManager, Configuration config, ModFileSystem modFileSystem,
- CommunicatorService communicator, MigrationManager migrationManager)
- {
- _modManager = modManager;
- _modImportManager = modImportManager;
- _config = config;
- _modFileSystem = modFileSystem;
- _communicator = communicator;
- _migrationManager = migrationManager;
- _communicator.ModPathChanged.Subscribe(OnModPathChanged, ModPathChanged.Priority.ApiMods);
- }
-
- private void OnModPathChanged(ModPathChangeType type, Mod mod, DirectoryInfo? oldDirectory, DirectoryInfo? newDirectory)
- {
- switch (type)
- {
- case ModPathChangeType.Deleted when oldDirectory != null: ModDeleted?.Invoke(oldDirectory.Name); break;
- case ModPathChangeType.Added when newDirectory != null: ModAdded?.Invoke(newDirectory.Name); break;
- case ModPathChangeType.Moved when newDirectory != null && oldDirectory != null:
- ModMoved?.Invoke(oldDirectory.Name, newDirectory.Name);
- break;
- }
- }
-
- public void Dispose()
- {
- _communicator.ModPathChanged.Unsubscribe(OnModPathChanged);
- }
-
- public Dictionary GetModList()
- => _modManager.ToDictionary(m => m.ModPath.Name, m => m.Name.Text);
-
- public PenumbraApiEc InstallMod(string modFilePackagePath)
- {
- if (!File.Exists(modFilePackagePath))
- return ApiHelpers.Return(PenumbraApiEc.FileMissing, ApiHelpers.Args("ModFilePackagePath", modFilePackagePath));
-
- _modImportManager.AddUnpack(modFilePackagePath);
- return ApiHelpers.Return(PenumbraApiEc.Success, ApiHelpers.Args("ModFilePackagePath", modFilePackagePath));
- }
-
- public PenumbraApiEc ReloadMod(string modDirectory, string modName)
- {
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, ApiHelpers.Args("ModDirectory", modDirectory, "ModName", modName));
-
- _modManager.ReloadMod(mod);
- return ApiHelpers.Return(PenumbraApiEc.Success, ApiHelpers.Args("ModDirectory", modDirectory, "ModName", modName));
- }
-
- public PenumbraApiEc AddMod(string modDirectory)
- {
- var args = ApiHelpers.Args("ModDirectory", modDirectory);
-
- var dir = new DirectoryInfo(Path.Join(_modManager.BasePath.FullName, Path.GetFileName(modDirectory)));
- if (!dir.Exists)
- return ApiHelpers.Return(PenumbraApiEc.FileMissing, args);
-
- if (dir.Parent == null
- || Path.TrimEndingDirectorySeparator(Path.GetFullPath(_modManager.BasePath.FullName))
- != Path.TrimEndingDirectorySeparator(Path.GetFullPath(dir.Parent.FullName)))
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- _modManager.AddMod(dir, true);
- if (_config.MigrateImportedModelsToV6)
- {
- _migrationManager.MigrateMdlDirectory(dir.FullName, false);
- _migrationManager.Await();
- }
-
- if (_config.UseFileSystemCompression)
- new FileCompactor(Penumbra.Log).StartMassCompact(dir.EnumerateFiles("*.*", SearchOption.AllDirectories),
- CompressionAlgorithm.Xpress8K, false);
-
- return ApiHelpers.Return(PenumbraApiEc.Success, args);
- }
-
- public PenumbraApiEc DeleteMod(string modDirectory, string modName)
- {
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.NothingChanged, ApiHelpers.Args("ModDirectory", modDirectory, "ModName", modName));
-
- _modManager.DeleteMod(mod);
- return ApiHelpers.Return(PenumbraApiEc.Success, ApiHelpers.Args("ModDirectory", modDirectory, "ModName", modName));
- }
-
- public event Action? ModDeleted;
- public event Action? ModAdded;
- public event Action? ModMoved;
-
- public event Action? CreatingPcp
- {
- add => _communicator.PcpCreation.Subscribe(value!, PcpCreation.Priority.ModsApi);
- remove => _communicator.PcpCreation.Unsubscribe(value!);
- }
-
- public event Action? ParsingPcp
- {
- add => _communicator.PcpParsing.Subscribe(value!, PcpParsing.Priority.ModsApi);
- remove => _communicator.PcpParsing.Unsubscribe(value!);
- }
-
- public (PenumbraApiEc, string, bool, bool) GetModPath(string modDirectory, string modName)
- {
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod)
- || !_modFileSystem.TryGetValue(mod, out var leaf))
- return (PenumbraApiEc.ModMissing, string.Empty, false, false);
-
- var fullPath = leaf.FullName();
- var isDefault = ModFileSystem.ModHasDefaultPath(mod, fullPath);
- var isNameDefault = isDefault || ModFileSystem.ModHasDefaultPath(mod, leaf.Name);
- return (PenumbraApiEc.Success, fullPath, !isDefault, !isNameDefault);
- }
-
- public PenumbraApiEc SetModPath(string modDirectory, string modName, string newPath)
- {
- if (newPath.Length == 0)
- return PenumbraApiEc.InvalidArgument;
-
- if (!_modManager.TryGetMod(modDirectory, modName, out var mod)
- || !_modFileSystem.TryGetValue(mod, out var leaf))
- return PenumbraApiEc.ModMissing;
-
- try
- {
- _modFileSystem.RenameAndMove(leaf, newPath);
- return PenumbraApiEc.Success;
- }
- catch
- {
- return PenumbraApiEc.PathRenameFailed;
- }
- }
-
- public Dictionary GetChangedItems(string modDirectory, string modName)
- => _modManager.TryGetMod(modDirectory, modName, out var mod)
- ? mod.ChangedItems.ToDictionary(kvp => kvp.Key, kvp => kvp.Value?.ToInternalObject())
- : [];
-
- public IReadOnlyDictionary> GetChangedItemAdapterDictionary()
- => new ModChangedItemAdapter(new WeakReference(_modManager));
-
- public IReadOnlyList<(string ModDirectory, IReadOnlyDictionary ChangedItems)> GetChangedItemAdapterList()
- => new ModChangedItemAdapter(new WeakReference(_modManager));
-}
diff --git a/Penumbra/Api/Api/PenumbraApi.cs b/Penumbra/Api/Api/PenumbraApi.cs
deleted file mode 100644
index c4026c72..00000000
--- a/Penumbra/Api/Api/PenumbraApi.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using OtterGui.Services;
-
-namespace Penumbra.Api.Api;
-
-public class PenumbraApi(
- CollectionApi collection,
- EditingApi editing,
- GameStateApi gameState,
- MetaApi meta,
- ModsApi mods,
- ModSettingsApi modSettings,
- PluginStateApi pluginState,
- RedrawApi redraw,
- ResolveApi resolve,
- ResourceTreeApi resourceTree,
- TemporaryApi temporary,
- UiApi ui) : IDisposable, IApiService, IPenumbraApi
-{
- public const int BreakingVersion = 5;
- public const int FeatureVersion = 13;
-
- public void Dispose()
- {
- Valid = false;
- }
-
- public (int Breaking, int Feature) ApiVersion
- => (BreakingVersion, FeatureVersion);
-
- public bool Valid { get; private set; } = true;
- public IPenumbraApiCollection Collection { get; } = collection;
- public IPenumbraApiEditing Editing { get; } = editing;
- public IPenumbraApiGameState GameState { get; } = gameState;
- public IPenumbraApiMeta Meta { get; } = meta;
- public IPenumbraApiMods Mods { get; } = mods;
- public IPenumbraApiModSettings ModSettings { get; } = modSettings;
- public IPenumbraApiPluginState PluginState { get; } = pluginState;
- public IPenumbraApiRedraw Redraw { get; } = redraw;
- public IPenumbraApiResolve Resolve { get; } = resolve;
- public IPenumbraApiResourceTree ResourceTree { get; } = resourceTree;
- public IPenumbraApiTemporary Temporary { get; } = temporary;
- public IPenumbraApiUi Ui { get; } = ui;
-}
diff --git a/Penumbra/Api/Api/PluginStateApi.cs b/Penumbra/Api/Api/PluginStateApi.cs
deleted file mode 100644
index f74553d1..00000000
--- a/Penumbra/Api/Api/PluginStateApi.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Collections.Frozen;
-using Newtonsoft.Json;
-using OtterGui.Services;
-using Penumbra.Communication;
-using Penumbra.Mods;
-using Penumbra.Services;
-
-namespace Penumbra.Api.Api;
-
-public class PluginStateApi(Configuration config, CommunicatorService communicator) : IPenumbraApiPluginState, IApiService
-{
- public string GetModDirectory()
- => config.ModDirectory;
-
- public string GetConfiguration()
- => JsonConvert.SerializeObject(config, Formatting.Indented);
-
- public event Action? ModDirectoryChanged
- {
- add => communicator.ModDirectoryChanged.Subscribe(value!, Communication.ModDirectoryChanged.Priority.Api);
- remove => communicator.ModDirectoryChanged.Unsubscribe(value!);
- }
-
- public bool GetEnabledState()
- => config.EnableMods;
-
- public event Action? EnabledChange
- {
- add => communicator.EnabledChanged.Subscribe(value!, EnabledChanged.Priority.Api);
- remove => communicator.EnabledChanged.Unsubscribe(value!);
- }
-
- public FrozenSet SupportedFeatures
- => FeatureChecker.SupportedFeatures.ToFrozenSet();
-
- public string[] CheckSupportedFeatures(IEnumerable requiredFeatures)
- => requiredFeatures.Where(f => !FeatureChecker.Supported(f)).ToArray();
-}
diff --git a/Penumbra/Api/Api/RedrawApi.cs b/Penumbra/Api/Api/RedrawApi.cs
deleted file mode 100644
index 08f1f9df..00000000
--- a/Penumbra/Api/Api/RedrawApi.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Plugin.Services;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.GameData.Interop;
-using Penumbra.Interop.Services;
-
-namespace Penumbra.Api.Api;
-
-public class RedrawApi(RedrawService redrawService, IFramework framework, CollectionManager collections, ObjectManager objects, ApiHelpers helpers) : IPenumbraApiRedraw, IApiService
-{
- public void RedrawObject(int gameObjectIndex, RedrawType setting)
- {
- framework.RunOnFrameworkThread(() => redrawService.RedrawObject(gameObjectIndex, setting));
- }
-
- public void RedrawObject(string name, RedrawType setting)
- {
- framework.RunOnFrameworkThread(() => redrawService.RedrawObject(name, setting));
- }
-
- public void RedrawObject(IGameObject? gameObject, RedrawType setting)
- {
- framework.RunOnFrameworkThread(() => redrawService.RedrawObject(gameObject, setting));
- }
-
- public void RedrawAll(RedrawType setting)
- {
- framework.RunOnFrameworkThread(() => redrawService.RedrawAll(setting));
- }
-
- public void RedrawCollectionMembers(Guid collectionId, RedrawType setting)
- {
-
- if (!collections.Storage.ById(collectionId, out var collection))
- collection = ModCollection.Empty;
- framework.RunOnFrameworkThread(() =>
- {
- foreach (var actor in objects.Objects)
- {
- helpers.AssociatedCollection(actor.ObjectIndex, out var modCollection);
- if (collection == modCollection)
- {
- redrawService.RedrawObject(actor.ObjectIndex, setting);
- }
- }
- });
- }
-
- public event GameObjectRedrawnDelegate? GameObjectRedrawn
- {
- add => redrawService.GameObjectRedrawn += value;
- remove => redrawService.GameObjectRedrawn -= value;
- }
-}
diff --git a/Penumbra/Api/Api/ResolveApi.cs b/Penumbra/Api/Api/ResolveApi.cs
deleted file mode 100644
index 00a0c86f..00000000
--- a/Penumbra/Api/Api/ResolveApi.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-using Dalamud.Plugin.Services;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.Interop.PathResolving;
-using Penumbra.Mods.Manager;
-using Penumbra.String.Classes;
-
-namespace Penumbra.Api.Api;
-
-public class ResolveApi(
- ModManager modManager,
- CollectionManager collectionManager,
- Configuration config,
- CollectionResolver collectionResolver,
- ApiHelpers helpers,
- IFramework framework) : IPenumbraApiResolve, IApiService
-{
- public string ResolveDefaultPath(string gamePath)
- => ResolvePath(gamePath, modManager, collectionManager.Active.Default);
-
- public string ResolveInterfacePath(string gamePath)
- => ResolvePath(gamePath, modManager, collectionManager.Active.Interface);
-
- public string ResolveGameObjectPath(string gamePath, int gameObjectIdx)
- {
- helpers.AssociatedCollection(gameObjectIdx, out var collection);
- return ResolvePath(gamePath, modManager, collection);
- }
-
- public string ResolvePlayerPath(string gamePath)
- => ResolvePath(gamePath, modManager, collectionResolver.PlayerCollection());
-
- public string[] ReverseResolveGameObjectPath(string moddedPath, int gameObjectIdx)
- {
- if (!config.EnableMods)
- return [moddedPath];
-
- helpers.AssociatedCollection(gameObjectIdx, out var collection);
- var ret = collection.ReverseResolvePath(new FullPath(moddedPath));
- return ret.Select(r => r.ToString()).ToArray();
- }
-
- public PenumbraApiEc ResolvePath(Guid collectionId, string gamePath, out string resolvedPath)
- {
- resolvedPath = gamePath;
- if (!collectionManager.Storage.ById(collectionId, out var collection))
- return PenumbraApiEc.CollectionMissing;
-
- if (!collection.HasCache)
- return PenumbraApiEc.CollectionInactive;
-
- resolvedPath = ResolvePath(gamePath, modManager, collection);
- return PenumbraApiEc.Success;
- }
-
- public string[] ReverseResolvePlayerPath(string moddedPath)
- {
- if (!config.EnableMods)
- return [moddedPath];
-
- var ret = collectionResolver.PlayerCollection().ReverseResolvePath(new FullPath(moddedPath));
- return ret.Select(r => r.ToString()).ToArray();
- }
-
- public (string[], string[][]) ResolvePlayerPaths(string[] forward, string[] reverse)
- {
- if (!config.EnableMods)
- return (forward, reverse.Select(p => new[]
- {
- p,
- }).ToArray());
-
- var playerCollection = collectionResolver.PlayerCollection();
- var resolved = forward.Select(p => ResolvePath(p, modManager, playerCollection)).ToArray();
- var reverseResolved = playerCollection.ReverseResolvePaths(reverse);
- return (resolved, reverseResolved.Select(a => a.Select(p => p.ToString()).ToArray()).ToArray());
- }
-
- public PenumbraApiEc ResolvePaths(Guid collectionId, string[] forward, string[] reverse, out string[] resolvedForward,
- out string[][] resolvedReverse)
- {
- resolvedForward = forward;
- resolvedReverse = [];
- if (!config.EnableMods)
- return PenumbraApiEc.Success;
-
- if (!collectionManager.Storage.ById(collectionId, out var collection))
- return PenumbraApiEc.CollectionMissing;
-
- if (!collection.HasCache)
- return PenumbraApiEc.CollectionInactive;
-
- resolvedForward = forward.Select(p => ResolvePath(p, modManager, collection)).ToArray();
- var reverseResolved = collection.ReverseResolvePaths(reverse);
- resolvedReverse = reverseResolved.Select(a => a.Select(p => p.ToString()).ToArray()).ToArray();
- return PenumbraApiEc.Success;
- }
-
- public async Task<(string[], string[][])> ResolvePlayerPathsAsync(string[] forward, string[] reverse)
- {
- if (!config.EnableMods)
- return (forward, reverse.Select(p => new[]
- {
- p,
- }).ToArray());
-
- return await Task.Run(async () =>
- {
- var playerCollection = await framework.RunOnFrameworkThread(collectionResolver.PlayerCollection).ConfigureAwait(false);
- var forwardTask = Task.Run(() =>
- {
- var forwardRet = new string[forward.Length];
- Parallel.For(0, forward.Length, idx => forwardRet[idx] = ResolvePath(forward[idx], modManager, playerCollection));
- return forwardRet;
- }).ConfigureAwait(false);
- var reverseTask = Task.Run(() => playerCollection.ReverseResolvePaths(reverse)).ConfigureAwait(false);
- var reverseResolved = (await reverseTask).Select(a => a.Select(p => p.ToString()).ToArray()).ToArray();
- return (await forwardTask, reverseResolved);
- }).ConfigureAwait(false);
- }
-
- /// Resolve a path given by string for a specific collection.
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- private string ResolvePath(string path, ModManager _, ModCollection collection)
- {
- if (!config.EnableMods)
- return path;
-
- var gamePath = Utf8GamePath.FromString(path, out var p) ? p : Utf8GamePath.Empty;
- var ret = collection.ResolvePath(gamePath);
- return ret?.ToString() ?? path;
- }
-}
diff --git a/Penumbra/Api/Api/ResourceTreeApi.cs b/Penumbra/Api/Api/ResourceTreeApi.cs
deleted file mode 100644
index dcec99bf..00000000
--- a/Penumbra/Api/Api/ResourceTreeApi.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Dalamud.Game.ClientState.Objects.Types;
-using Newtonsoft.Json.Linq;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.GameData.Interop;
-using Penumbra.Interop.ResourceTree;
-
-namespace Penumbra.Api.Api;
-
-public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectManager objects) : IPenumbraApiResourceTree, IApiService
-{
- public Dictionary>?[] GetGameObjectResourcePaths(params ushort[] gameObjects)
- {
- var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType();
- var resourceTrees = resourceTreeFactory.FromCharacters(characters, 0);
- var pathDictionaries = ResourceTreeApiHelper.GetResourcePathDictionaries(resourceTrees);
-
- return Array.ConvertAll(gameObjects, obj => pathDictionaries.GetValueOrDefault(obj));
- }
-
- public Dictionary>> GetPlayerResourcePaths()
- {
- var resourceTrees = resourceTreeFactory.FromObjectTable(ResourceTreeFactory.Flags.LocalPlayerRelatedOnly);
- return ResourceTreeApiHelper.GetResourcePathDictionaries(resourceTrees);
- }
-
- public GameResourceDict?[] GetGameObjectResourcesOfType(ResourceType type, bool withUiData,
- params ushort[] gameObjects)
- {
- var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType();
- var resourceTrees = resourceTreeFactory.FromCharacters(characters, withUiData ? ResourceTreeFactory.Flags.WithUiData : 0);
- var resDictionaries = ResourceTreeApiHelper.GetResourcesOfType(resourceTrees, type);
-
- return Array.ConvertAll(gameObjects, obj => resDictionaries.GetValueOrDefault(obj));
- }
-
- public Dictionary GetPlayerResourcesOfType(ResourceType type,
- bool withUiData)
- {
- var resourceTrees = resourceTreeFactory.FromObjectTable(ResourceTreeFactory.Flags.LocalPlayerRelatedOnly
- | (withUiData ? ResourceTreeFactory.Flags.WithUiData : 0));
- return ResourceTreeApiHelper.GetResourcesOfType(resourceTrees, type);
- }
-
- public JObject?[] GetGameObjectResourceTrees(bool withUiData, params ushort[] gameObjects)
- {
- var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType();
- var resourceTrees = resourceTreeFactory.FromCharacters(characters, withUiData ? ResourceTreeFactory.Flags.WithUiData : 0);
- var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);
-
- return Array.ConvertAll(gameObjects, obj => resDictionary.GetValueOrDefault(obj));
- }
-
- public Dictionary GetPlayerResourceTrees(bool withUiData)
- {
- var resourceTrees = resourceTreeFactory.FromObjectTable(ResourceTreeFactory.Flags.LocalPlayerRelatedOnly
- | (withUiData ? ResourceTreeFactory.Flags.WithUiData : 0));
- var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);
-
- return resDictionary;
- }
-}
diff --git a/Penumbra/Api/Api/TemporaryApi.cs b/Penumbra/Api/Api/TemporaryApi.cs
deleted file mode 100644
index 7567acd3..00000000
--- a/Penumbra/Api/Api/TemporaryApi.cs
+++ /dev/null
@@ -1,338 +0,0 @@
-using OtterGui.Log;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.GameData.Actors;
-using Penumbra.GameData.Interop;
-using Penumbra.Mods.Manager;
-using Penumbra.Mods.Settings;
-using Penumbra.String.Classes;
-
-namespace Penumbra.Api.Api;
-
-public class TemporaryApi(
- TempCollectionManager tempCollections,
- ObjectManager objects,
- ActorManager actors,
- CollectionManager collectionManager,
- TempModManager tempMods,
- ApiHelpers apiHelpers,
- ModManager modManager) : IPenumbraApiTemporary, IApiService
-{
- public (PenumbraApiEc, Guid) CreateTemporaryCollection(string identity, string name)
- {
- if (!IdentityChecker.Check(identity))
- return (PenumbraApiEc.InvalidCredentials, Guid.Empty);
-
- var collection = tempCollections.CreateTemporaryCollection(name);
- if (collection == Guid.Empty)
- return (PenumbraApiEc.UnknownError, collection);
- return (PenumbraApiEc.Success, collection);
- }
-
- public PenumbraApiEc DeleteTemporaryCollection(Guid collectionId)
- => tempCollections.RemoveTemporaryCollection(collectionId)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.CollectionMissing;
-
- public PenumbraApiEc AssignTemporaryCollection(Guid collectionId, int actorIndex, bool forceAssignment)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ActorIndex", actorIndex, "Forced", forceAssignment);
- if (actorIndex < 0 || actorIndex >= objects.TotalCount)
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- var identifier = actors.FromObject(objects[actorIndex], out _, false, false, true);
- if (!identifier.IsValid)
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- if (!tempCollections.CollectionById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (forceAssignment)
- {
- if (tempCollections.Collections.ContainsKey(identifier) && !tempCollections.Collections.Delete(identifier))
- return ApiHelpers.Return(PenumbraApiEc.AssignmentDeletionFailed, args);
- }
- else if (tempCollections.Collections.ContainsKey(identifier)
- || collectionManager.Active.Individuals.ContainsKey(identifier))
- {
- return ApiHelpers.Return(PenumbraApiEc.CharacterCollectionExists, args);
- }
-
- var group = tempCollections.Collections.GetGroup(identifier);
- var ret = tempCollections.AddIdentifier(collection, group)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.UnknownError;
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc AddTemporaryModAll(string tag, Dictionary paths, string manipString, int priority)
- {
- var args = ApiHelpers.Args("Tag", tag, "#Paths", paths.Count, "ManipString", manipString, "Priority", priority);
- if (!ConvertPaths(paths, out var p))
- return ApiHelpers.Return(PenumbraApiEc.InvalidGamePath, args);
-
- if (!MetaApi.ConvertManips(manipString, out var m, out _))
- return ApiHelpers.Return(PenumbraApiEc.InvalidManipulation, args);
-
- var ret = tempMods.Register(tag, null, p, m, new ModPriority(priority)) switch
- {
- RedirectResult.Success => PenumbraApiEc.Success,
- _ => PenumbraApiEc.UnknownError,
- };
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc AddTemporaryMod(string tag, Guid collectionId, Dictionary paths, string manipString, int priority)
- {
- var args = ApiHelpers.Args("Tag", tag, "CollectionId", collectionId, "#Paths", paths.Count, "ManipString",
- manipString, "Priority", priority);
-
- if (collectionId == Guid.Empty)
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- if (!tempCollections.CollectionById(collectionId, out var collection)
- && !collectionManager.Storage.ById(collectionId, out collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- if (!ConvertPaths(paths, out var p))
- return ApiHelpers.Return(PenumbraApiEc.InvalidGamePath, args);
-
- if (!MetaApi.ConvertManips(manipString, out var m, out _))
- return ApiHelpers.Return(PenumbraApiEc.InvalidManipulation, args);
-
- var ret = tempMods.Register(tag, collection, p, m, new ModPriority(priority)) switch
- {
- RedirectResult.Success => PenumbraApiEc.Success,
- _ => PenumbraApiEc.UnknownError,
- };
- return ApiHelpers.Return(ret, args);
- }
-
- public PenumbraApiEc RemoveTemporaryModAll(string tag, int priority)
- {
- var ret = tempMods.Unregister(tag, null, new ModPriority(priority)) switch
- {
- RedirectResult.Success => PenumbraApiEc.Success,
- RedirectResult.NotRegistered => PenumbraApiEc.NothingChanged,
- _ => PenumbraApiEc.UnknownError,
- };
- return ApiHelpers.Return(ret, ApiHelpers.Args("Tag", tag, "Priority", priority));
- }
-
- public PenumbraApiEc RemoveTemporaryMod(string tag, Guid collectionId, int priority)
- {
- var args = ApiHelpers.Args("Tag", tag, "CollectionId", collectionId, "Priority", priority);
-
- if (!tempCollections.CollectionById(collectionId, out var collection)
- && !collectionManager.Storage.ById(collectionId, out collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- var ret = tempMods.Unregister(tag, collection, new ModPriority(priority)) switch
- {
- RedirectResult.Success => PenumbraApiEc.Success,
- RedirectResult.NotRegistered => PenumbraApiEc.NothingChanged,
- _ => PenumbraApiEc.UnknownError,
- };
- return ApiHelpers.Return(ret, args);
- }
-
- public (PenumbraApiEc, (bool, bool, int, Dictionary>)?, string) QueryTemporaryModSettings(Guid collectionId,
- string modDirectory, string modName, int key)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName);
- if (!collectionManager.Storage.ById(collectionId, out var collection))
- return (ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args), null, string.Empty);
-
- return QueryTemporaryModSettings(args, collection, modDirectory, modName, key);
- }
-
- public (PenumbraApiEc ErrorCode, (bool, bool, int, Dictionary>)? Settings, string Source)
- QueryTemporaryModSettingsPlayer(int objectIndex,
- string modDirectory, string modName, int key)
- {
- var args = ApiHelpers.Args("ObjectIndex", objectIndex, "ModDirectory", modDirectory, "ModName", modName);
- if (!apiHelpers.AssociatedCollection(objectIndex, out var collection))
- return (ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args), null, string.Empty);
-
- return QueryTemporaryModSettings(args, collection, modDirectory, modName, key);
- }
-
- private (PenumbraApiEc ErrorCode, (bool, bool, int, Dictionary>)? Settings, string Source) QueryTemporaryModSettings(
- in LazyString args, ModCollection collection, string modDirectory, string modName, int key)
- {
- if (!modManager.TryGetMod(modDirectory, modName, out var mod))
- return (ApiHelpers.Return(PenumbraApiEc.ModMissing, args), null, string.Empty);
-
- if (collection.Identity.Index <= 0)
- return (ApiHelpers.Return(PenumbraApiEc.Success, args), null, string.Empty);
-
- var settings = collection.GetTempSettings(mod.Index);
- if (settings == null)
- return (ApiHelpers.Return(PenumbraApiEc.Success, args), null, string.Empty);
-
- if (settings.Lock > 0 && settings.Lock != key)
- return (ApiHelpers.Return(PenumbraApiEc.TemporarySettingDisallowed, args), null, settings.Source);
-
- return (ApiHelpers.Return(PenumbraApiEc.Success, args),
- (settings.ForceInherit, settings.Enabled, settings.Priority.Value, settings.ConvertToShareable(mod).Settings), settings.Source);
- }
-
-
- public PenumbraApiEc SetTemporaryModSettings(Guid collectionId, string modDirectory, string modName, bool inherit, bool enabled,
- int priority,
- IReadOnlyDictionary> options, string source, int key)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "Inherit", inherit,
- "Enabled", enabled,
- "Priority", priority, "Options", options, "Source", source, "Key", key);
- if (!collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- return SetTemporaryModSettings(args, collection, modDirectory, modName, inherit, enabled, priority, options, source, key);
- }
-
- public PenumbraApiEc SetTemporaryModSettingsPlayer(int objectIndex, string modDirectory, string modName, bool inherit, bool enabled,
- int priority,
- IReadOnlyDictionary> options, string source, int key)
- {
- var args = ApiHelpers.Args("ObjectIndex", objectIndex, "ModDirectory", modDirectory, "ModName", modName, "Inherit", inherit, "Enabled",
- enabled,
- "Priority", priority, "Options", options, "Source", source, "Key", key);
- if (!apiHelpers.AssociatedCollection(objectIndex, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- return SetTemporaryModSettings(args, collection, modDirectory, modName, inherit, enabled, priority, options, source, key);
- }
-
- private PenumbraApiEc SetTemporaryModSettings(in LazyString args, ModCollection collection, string modDirectory, string modName,
- bool inherit, bool enabled, int priority, IReadOnlyDictionary> options, string source, int key)
- {
- if (collection.Identity.Index <= 0)
- return ApiHelpers.Return(PenumbraApiEc.TemporarySettingImpossible, args);
-
- if (!modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- if (!collectionManager.Editor.CanSetTemporarySettings(collection, mod, key))
- if (collection.GetTempSettings(mod.Index) is { Lock: > 0 } oldSettings && oldSettings.Lock != key)
- return ApiHelpers.Return(PenumbraApiEc.TemporarySettingDisallowed, args);
-
- var newSettings = new TemporaryModSettings()
- {
- ForceInherit = inherit,
- Enabled = enabled,
- Priority = new ModPriority(priority),
- Lock = key,
- Source = source,
- Settings = SettingList.Default(mod),
- };
-
-
- foreach (var (groupName, optionNames) in options)
- {
- var ec = ModSettingsApi.ConvertModSetting(mod, groupName, optionNames, out var groupIdx, out var setting);
- if (ec != PenumbraApiEc.Success)
- return ApiHelpers.Return(ec, args);
-
- newSettings.Settings[groupIdx] = setting;
- }
-
- if (collectionManager.Editor.SetTemporarySettings(collection, mod, newSettings, key))
- return ApiHelpers.Return(PenumbraApiEc.Success, args);
-
- // This should not happen since all error cases had been checked before.
- return ApiHelpers.Return(PenumbraApiEc.UnknownError, args);
- }
-
- public PenumbraApiEc RemoveTemporaryModSettings(Guid collectionId, string modDirectory, string modName, int key)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "ModDirectory", modDirectory, "ModName", modName, "Key", key);
- if (!collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- return RemoveTemporaryModSettings(args, collection, modDirectory, modName, key);
- }
-
- public PenumbraApiEc RemoveTemporaryModSettingsPlayer(int objectIndex, string modDirectory, string modName, int key)
- {
- var args = ApiHelpers.Args("ObjectIndex", objectIndex, "ModDirectory", modDirectory, "ModName", modName, "Key", key);
- if (!apiHelpers.AssociatedCollection(objectIndex, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- return RemoveTemporaryModSettings(args, collection, modDirectory, modName, key);
- }
-
- private PenumbraApiEc RemoveTemporaryModSettings(in LazyString args, ModCollection collection, string modDirectory, string modName, int key)
- {
- if (collection.Identity.Index <= 0)
- return ApiHelpers.Return(PenumbraApiEc.NothingChanged, args);
-
- if (!modManager.TryGetMod(modDirectory, modName, out var mod))
- return ApiHelpers.Return(PenumbraApiEc.ModMissing, args);
-
- if (collection.GetTempSettings(mod.Index) is null)
- return ApiHelpers.Return(PenumbraApiEc.NothingChanged, args);
-
- if (!collectionManager.Editor.SetTemporarySettings(collection, mod, null, key))
- return ApiHelpers.Return(PenumbraApiEc.TemporarySettingDisallowed, args);
-
- return ApiHelpers.Return(PenumbraApiEc.Success, args);
- }
-
- public PenumbraApiEc RemoveAllTemporaryModSettings(Guid collectionId, int key)
- {
- var args = ApiHelpers.Args("CollectionId", collectionId, "Key", key);
- if (!collectionManager.Storage.ById(collectionId, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.CollectionMissing, args);
-
- return RemoveAllTemporaryModSettings(args, collection, key);
- }
-
- public PenumbraApiEc RemoveAllTemporaryModSettingsPlayer(int objectIndex, int key)
- {
- var args = ApiHelpers.Args("ObjectIndex", objectIndex, "Key", key);
- if (!apiHelpers.AssociatedCollection(objectIndex, out var collection))
- return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
-
- return RemoveAllTemporaryModSettings(args, collection, key);
- }
-
- private PenumbraApiEc RemoveAllTemporaryModSettings(in LazyString args, ModCollection collection, int key)
- {
- if (collection.Identity.Index <= 0)
- return ApiHelpers.Return(PenumbraApiEc.NothingChanged, args);
-
- var numRemoved = collectionManager.Editor.ClearTemporarySettings(collection, key);
- return ApiHelpers.Return(numRemoved > 0 ? PenumbraApiEc.Success : PenumbraApiEc.NothingChanged, args);
- }
-
-
- ///
- /// Convert a dictionary of strings to a dictionary of game paths to full paths.
- /// Only returns true if all paths can successfully be converted and added.
- ///
- private static bool ConvertPaths(IReadOnlyDictionary redirections,
- [NotNullWhen(true)] out Dictionary? paths)
- {
- paths = new Dictionary(redirections.Count);
- foreach (var (gString, fString) in redirections)
- {
- if (!Utf8GamePath.FromString(gString, out var path))
- {
- paths = null;
- return false;
- }
-
- var fullPath = new FullPath(fString);
- if (!paths.TryAdd(path, fullPath))
- {
- paths = null;
- return false;
- }
- }
-
- return true;
- }
-}
diff --git a/Penumbra/Api/Api/UiApi.cs b/Penumbra/Api/Api/UiApi.cs
deleted file mode 100644
index 6fb116f3..00000000
--- a/Penumbra/Api/Api/UiApi.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Communication;
-using Penumbra.GameData.Data;
-using Penumbra.Mods.Manager;
-using Penumbra.Services;
-using Penumbra.UI;
-using Penumbra.UI.Integration;
-using Penumbra.UI.Tabs;
-
-namespace Penumbra.Api.Api;
-
-public class UiApi : IPenumbraApiUi, IApiService, IDisposable
-{
- private readonly CommunicatorService _communicator;
- private readonly ConfigWindow _configWindow;
- private readonly ModManager _modManager;
- private readonly IntegrationSettingsRegistry _integrationSettings;
-
- public UiApi(CommunicatorService communicator, ConfigWindow configWindow, ModManager modManager, IntegrationSettingsRegistry integrationSettings)
- {
- _communicator = communicator;
- _configWindow = configWindow;
- _modManager = modManager;
- _integrationSettings = integrationSettings;
- _communicator.ChangedItemHover.Subscribe(OnChangedItemHover, ChangedItemHover.Priority.Default);
- _communicator.ChangedItemClick.Subscribe(OnChangedItemClick, ChangedItemClick.Priority.Default);
- }
-
- public void Dispose()
- {
- _communicator.ChangedItemHover.Unsubscribe(OnChangedItemHover);
- _communicator.ChangedItemClick.Unsubscribe(OnChangedItemClick);
- }
-
- public event Action? ChangedItemTooltip;
-
- public event Action? ChangedItemClicked;
-
- public event Action? PreSettingsTabBarDraw
- {
- add => _communicator.PreSettingsTabBarDraw.Subscribe(value!, Communication.PreSettingsTabBarDraw.Priority.Default);
- remove => _communicator.PreSettingsTabBarDraw.Unsubscribe(value!);
- }
-
- public event Action? PreSettingsPanelDraw
- {
- add => _communicator.PreSettingsPanelDraw.Subscribe(value!, Communication.PreSettingsPanelDraw.Priority.Default);
- remove => _communicator.PreSettingsPanelDraw.Unsubscribe(value!);
- }
-
- public event Action? PostEnabledDraw
- {
- add => _communicator.PostEnabledDraw.Subscribe(value!, Communication.PostEnabledDraw.Priority.Default);
- remove => _communicator.PostEnabledDraw.Unsubscribe(value!);
- }
-
- public event Action? PostSettingsPanelDraw
- {
- add => _communicator.PostSettingsPanelDraw.Subscribe(value!, Communication.PostSettingsPanelDraw.Priority.Default);
- remove => _communicator.PostSettingsPanelDraw.Unsubscribe(value!);
- }
-
- public PenumbraApiEc OpenMainWindow(TabType tab, string modDirectory, string modName)
- {
- _configWindow.IsOpen = true;
- if (!Enum.IsDefined(tab))
- return PenumbraApiEc.InvalidArgument;
-
- if (tab == TabType.Mods && (modDirectory.Length > 0 || modName.Length > 0))
- {
- if (_modManager.TryGetMod(modDirectory, modName, out var mod))
- _communicator.SelectTab.Invoke(tab, mod);
- else
- return PenumbraApiEc.ModMissing;
- }
- else if (tab != TabType.None)
- {
- _communicator.SelectTab.Invoke(tab, null);
- }
-
- return PenumbraApiEc.Success;
- }
-
- public void CloseMainWindow()
- => _configWindow.IsOpen = false;
-
- private void OnChangedItemClick(MouseButton button, IIdentifiedObjectData data)
- {
- if (ChangedItemClicked == null)
- return;
-
- var (type, id) = data.ToApiObject();
- ChangedItemClicked.Invoke(button, type, id);
- }
-
- private void OnChangedItemHover(IIdentifiedObjectData data)
- {
- if (ChangedItemTooltip == null)
- return;
-
- var (type, id) = data.ToApiObject();
- ChangedItemTooltip.Invoke(type, id);
- }
-
- public PenumbraApiEc RegisterSettingsSection(Action draw)
- => _integrationSettings.RegisterSection(draw);
-
- public PenumbraApiEc UnregisterSettingsSection(Action draw)
- => _integrationSettings.UnregisterSection(draw)
- ? PenumbraApiEc.Success
- : PenumbraApiEc.NothingChanged;
-}
diff --git a/Penumbra/Api/DalamudSubstitutionProvider.cs b/Penumbra/Api/DalamudSubstitutionProvider.cs
deleted file mode 100644
index e10dc461..00000000
--- a/Penumbra/Api/DalamudSubstitutionProvider.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-using Dalamud.Interface;
-using Dalamud.Plugin.Services;
-using OtterGui.Services;
-using Penumbra.Collections;
-using Penumbra.Collections.Manager;
-using Penumbra.Communication;
-using Penumbra.Mods.Editor;
-using Penumbra.Services;
-using Penumbra.String.Classes;
-
-namespace Penumbra.Api;
-
-public class DalamudSubstitutionProvider : IDisposable, IApiService
-{
- private readonly ITextureSubstitutionProvider _substitution;
- private readonly IUiBuilder _uiBuilder;
- private readonly ActiveCollectionData _activeCollectionData;
- private readonly Configuration _config;
- private readonly CommunicatorService _communicator;
-
- public bool Enabled
- => _config.UseDalamudUiTextureRedirection;
-
- public DalamudSubstitutionProvider(ITextureSubstitutionProvider substitution, ActiveCollectionData activeCollectionData,
- Configuration config, CommunicatorService communicator, IUiBuilder ui)
- {
- _substitution = substitution;
- _uiBuilder = ui;
- _activeCollectionData = activeCollectionData;
- _config = config;
- _communicator = communicator;
- if (Enabled)
- Subscribe();
- }
-
- public void Set(bool value)
- {
- if (value)
- Enable();
- else
- Disable();
- }
-
- public void ResetSubstitutions(IEnumerable paths)
- {
- if (!_uiBuilder.UiPrepared)
- return;
-
- var transformed = paths
- .Where(p => (p.Path.StartsWith("ui/"u8) || p.Path.StartsWith("common/font/"u8)) && p.Path.EndsWith(".tex"u8))
- .Select(p => p.ToString());
- _substitution.InvalidatePaths(transformed);
- }
-
- public void Enable()
- {
- if (Enabled)
- return;
-
- _config.UseDalamudUiTextureRedirection = true;
- _config.Save();
- Subscribe();
- }
-
- public void Disable()
- {
- if (!Enabled)
- return;
-
- Unsubscribe();
- _config.UseDalamudUiTextureRedirection = false;
- _config.Save();
- }
-
- public void Dispose()
- => Unsubscribe();
-
- private void OnCollectionChange(CollectionType type, ModCollection? oldCollection, ModCollection? newCollection, string _)
- {
- if (type is not CollectionType.Interface)
- return;
-
- var enumerable = oldCollection?.ResolvedFiles.Keys ?? Array.Empty().AsEnumerable();
- enumerable = enumerable.Concat(newCollection?.ResolvedFiles.Keys ?? Array.Empty().AsEnumerable());
- ResetSubstitutions(enumerable);
- }
-
- private void OnResolvedFileChange(ModCollection collection, ResolvedFileChanged.Type type, Utf8GamePath key, FullPath _1, FullPath _2,
- IMod? _3)
- {
- if (_activeCollectionData.Interface != collection)
- return;
-
- switch (type)
- {
- case ResolvedFileChanged.Type.Added:
- case ResolvedFileChanged.Type.Removed:
- case ResolvedFileChanged.Type.Replaced:
- ResetSubstitutions([key]);
- break;
- case ResolvedFileChanged.Type.FullRecomputeStart:
- case ResolvedFileChanged.Type.FullRecomputeFinished:
- ResetSubstitutions(collection.ResolvedFiles.Keys);
- break;
- }
- }
-
- private void OnEnabledChange(bool state)
- {
- if (state)
- OnCollectionChange(CollectionType.Interface, null, _activeCollectionData.Interface, string.Empty);
- else
- OnCollectionChange(CollectionType.Interface, _activeCollectionData.Interface, null, string.Empty);
- }
-
- private void Substitute(string path, ref string? replacementPath)
- {
- // Do not replace when not enabled.
- if (!_config.EnableMods)
- return;
-
- // Let other plugins prioritize replacement paths.
- if (replacementPath != null)
- return;
-
- // Only replace interface textures.
- if (!path.StartsWith("ui/") && !path.StartsWith("common/font/"))
- return;
-
- try
- {
- if (!Utf8GamePath.FromString(path, out var utf8Path))
- return;
-
- var resolved = _activeCollectionData.Interface.ResolvePath(utf8Path);
- replacementPath = resolved?.FullName;
- }
- catch
- {
- // ignored
- }
- }
-
- private void Subscribe()
- {
- _substitution.InterceptTexDataLoad += Substitute;
- _communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.DalamudSubstitutionProvider);
- _communicator.ResolvedFileChanged.Subscribe(OnResolvedFileChange, ResolvedFileChanged.Priority.DalamudSubstitutionProvider);
- _communicator.EnabledChanged.Subscribe(OnEnabledChange, EnabledChanged.Priority.DalamudSubstitutionProvider);
- OnCollectionChange(CollectionType.Interface, null, _activeCollectionData.Interface, string.Empty);
- }
-
- private void Unsubscribe()
- {
- _substitution.InterceptTexDataLoad -= Substitute;
- _communicator.CollectionChange.Unsubscribe(OnCollectionChange);
- _communicator.ResolvedFileChanged.Unsubscribe(OnResolvedFileChange);
- _communicator.EnabledChanged.Unsubscribe(OnEnabledChange);
- OnCollectionChange(CollectionType.Interface, _activeCollectionData.Interface, null, string.Empty);
- }
-}
diff --git a/Penumbra/Api/HttpApi.cs b/Penumbra/Api/HttpApi.cs
deleted file mode 100644
index 79348a88..00000000
--- a/Penumbra/Api/HttpApi.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-using Dalamud.Plugin.Services;
-using EmbedIO;
-using EmbedIO.Routing;
-using EmbedIO.WebApi;
-using OtterGui.Services;
-using Penumbra.Api.Api;
-using Penumbra.Api.Enums;
-using Penumbra.Mods.Settings;
-
-namespace Penumbra.Api;
-
-public class HttpApi : IDisposable, IApiService
-{
- private partial class Controller : WebApiController
- {
- // @formatter:off
- [Route( HttpVerbs.Get, "/moddirectory" )] public partial string GetModDirectory();
- [Route( HttpVerbs.Get, "/mods" )] public partial object? GetMods();
- [Route( HttpVerbs.Post, "/redraw" )] public partial Task Redraw();
- [Route( HttpVerbs.Post, "/redrawAll" )] public partial Task RedrawAll();
- [Route( HttpVerbs.Post, "/reloadmod" )] public partial Task ReloadMod();
- [Route( HttpVerbs.Post, "/installmod" )] public partial Task InstallMod();
- [Route( HttpVerbs.Post, "/openwindow" )] public partial void OpenWindow();
- [Route( HttpVerbs.Post, "/focusmod" )] public partial Task FocusMod();
- [Route( HttpVerbs.Post, "/setmodsettings")] public partial Task SetModSettings();
- // @formatter:on
- }
-
- public const string Prefix = "http://localhost:42069/";
-
- private readonly IPenumbraApi _api;
- private readonly IFramework _framework;
- private WebServer? _server;
-
- public HttpApi(Configuration config, IPenumbraApi api, IFramework framework)
- {
- _api = api;
- _framework = framework;
- if (config.EnableHttpApi)
- CreateWebServer();
- }
-
- public bool Enabled
- => _server != null;
-
- public void CreateWebServer()
- {
- ShutdownWebServer();
-
- _server = new WebServer(o => o
- .WithUrlPrefix(Prefix)
- .WithMode(HttpListenerMode.EmbedIO))
- .WithCors(Prefix)
- .WithWebApi("/api", m => m.WithController(() => new Controller(_api, _framework)));
-
- _server.StateChanged += (_, e) => Penumbra.Log.Information($"WebServer New State - {e.NewState}");
- _server.RunAsync();
- }
-
- public void ShutdownWebServer()
- {
- _server?.Dispose();
- _server = null;
- }
-
- public void Dispose()
- => ShutdownWebServer();
-
- private partial class Controller(IPenumbraApi api, IFramework framework)
- {
- public partial string GetModDirectory()
- {
- Penumbra.Log.Debug($"[HTTP] {nameof(GetModDirectory)} triggered.");
- return api.PluginState.GetModDirectory();
- }
-
- public partial object? GetMods()
- {
- Penumbra.Log.Debug($"[HTTP] {nameof(GetMods)} triggered.");
- return api.Mods.GetModList();
- }
-
- public async partial Task Redraw()
- {
- var data = await HttpContext.GetRequestDataAsync().ConfigureAwait(false);
- Penumbra.Log.Debug($"[HTTP] [{Environment.CurrentManagedThreadId}] {nameof(Redraw)} triggered with {data}.");
- await framework.RunOnFrameworkThread(() =>
- {
- if (data.ObjectTableIndex >= 0)
- api.Redraw.RedrawObject(data.ObjectTableIndex, data.Type);
- else
- api.Redraw.RedrawAll(data.Type);
- }).ConfigureAwait(false);
- }
-
- public async partial Task RedrawAll()
- {
- Penumbra.Log.Debug($"[HTTP] {nameof(RedrawAll)} triggered.");
- await framework.RunOnFrameworkThread(() => { api.Redraw.RedrawAll(RedrawType.Redraw); }).ConfigureAwait(false);
- }
-
- public async partial Task ReloadMod()
- {
- var data = await HttpContext.GetRequestDataAsync().ConfigureAwait(false);
- Penumbra.Log.Debug($"[HTTP] {nameof(ReloadMod)} triggered with {data}.");
- // Add the mod if it is not already loaded and if the directory name is given.
- // AddMod returns Success if the mod is already loaded.
- if (data.Path.Length != 0)
- api.Mods.AddMod(data.Path);
-
- // Reload the mod by path or name, which will also remove no-longer existing mods.
- api.Mods.ReloadMod(data.Path, data.Name);
- }
-
- public async partial Task InstallMod()
- {
- var data = await HttpContext.GetRequestDataAsync().ConfigureAwait(false);
- Penumbra.Log.Debug($"[HTTP] {nameof(InstallMod)} triggered with {data}.");
- if (data.Path.Length != 0)
- api.Mods.InstallMod(data.Path);
- }
-
- public partial void OpenWindow()
- {
- Penumbra.Log.Debug($"[HTTP] {nameof(OpenWindow)} triggered.");
- api.Ui.OpenMainWindow(TabType.Mods, string.Empty, string.Empty);
- }
-
- public async partial Task FocusMod()
- {
- var data = await HttpContext.GetRequestDataAsync().ConfigureAwait(false);
- Penumbra.Log.Debug($"[HTTP] {nameof(FocusMod)} triggered.");
- if (data.Path.Length != 0)
- api.Ui.OpenMainWindow(TabType.Mods, data.Path, data.Name);
- }
-
- public async partial Task SetModSettings()
- {
- var data = await HttpContext.GetRequestDataAsync().ConfigureAwait(false);
- Penumbra.Log.Debug($"[HTTP] {nameof(SetModSettings)} triggered.");
- await framework.RunOnFrameworkThread(() =>
- {
- var collection = data.CollectionId ?? api.Collection.GetCollection(ApiCollectionType.Current)!.Value.Id;
- if (data.Inherit.HasValue)
- {
- api.ModSettings.TryInheritMod(collection, data.ModPath, data.ModName, data.Inherit.Value);
- if (data.Inherit.Value)
- return;
- }
-
- if (data.State.HasValue)
- api.ModSettings.TrySetMod(collection, data.ModPath, data.ModName, data.State.Value);
- if (data.Priority.HasValue)
- api.ModSettings.TrySetModPriority(collection, data.ModPath, data.ModName, data.Priority.Value);
- foreach (var (group, settings) in data.Settings ?? [])
- api.ModSettings.TrySetModSettings(collection, data.ModPath, data.ModName, group, settings);
- }
- ).ConfigureAwait(false);
- }
-
- private record ModReloadData(string Path, string Name)
- {
- public ModReloadData()
- : this(string.Empty, string.Empty)
- { }
- }
-
- private record ModFocusData(string Path, string Name)
- {
- public ModFocusData()
- : this(string.Empty, string.Empty)
- { }
- }
-
- private record ModInstallData(string Path)
- {
- public ModInstallData()
- : this(string.Empty)
- { }
- }
-
- private record RedrawData(string Name, RedrawType Type, int ObjectTableIndex)
- {
- public RedrawData()
- : this(string.Empty, RedrawType.Redraw, -1)
- { }
- }
-
- private record SetModSettingsData(
- Guid? CollectionId,
- string ModPath,
- string ModName,
- bool? Inherit,
- bool? State,
- int? Priority,
- Dictionary>? Settings)
- {
- public SetModSettingsData()
- : this(null, string.Empty, string.Empty, null, null, null, null)
- {}
- }
- }
-}
diff --git a/Penumbra/Api/IPenumbraApi.cs b/Penumbra/Api/IPenumbraApi.cs
new file mode 100644
index 00000000..92d9ef3d
--- /dev/null
+++ b/Penumbra/Api/IPenumbraApi.cs
@@ -0,0 +1,47 @@
+using Dalamud.Game.ClientState.Objects.Types;
+using Lumina.Data;
+using Penumbra.GameData.Enums;
+
+namespace Penumbra.Api
+{
+ public interface IPenumbraApiBase
+ {
+ public int ApiVersion { get; }
+ public bool Valid { get; }
+ }
+
+ public delegate void ChangedItemHover( object? item );
+ public delegate void ChangedItemClick( MouseButton button, object? item );
+
+ public interface IPenumbraApi : IPenumbraApiBase
+ {
+ // Triggered when the user hovers over a listed changed object in a mod tab.
+ // Can be used to append tooltips.
+ public event ChangedItemHover? ChangedItemTooltip;
+ // Triggered when the user clicks a listed changed object in a mod tab.
+ public event ChangedItemClick? ChangedItemClicked;
+
+ // Queue redrawing of all actors of the given name with the given RedrawType.
+ public void RedrawObject( string name, RedrawType setting );
+
+ // Queue redrawing of the specific actor with the given RedrawType. Should only be used when the actor is sure to be valid.
+ public void RedrawObject( GameObject gameObject, RedrawType setting );
+
+ // Queue redrawing of all currently available actors with the given RedrawType.
+ public void RedrawAll( RedrawType setting );
+
+ // Resolve a given gamePath via Penumbra using the Default and Forced collections.
+ // Returns the given gamePath if penumbra would not manipulate it.
+ public string ResolvePath(string gamePath);
+
+ // Resolve a given gamePath via Penumbra using the character collection for the given name (if it exists) and the Forced collections.
+ // Returns the given gamePath if penumbra would not manipulate it.
+ public string ResolvePath( string gamePath, string characterName );
+
+ // Try to load a given gamePath with the resolved path from Penumbra.
+ public T? GetFile< T >( string gamePath ) where T : FileResource;
+
+ // Try to load a given gamePath with the resolved path from Penumbra.
+ public T? GetFile( string gamePath, string characterName ) where T : FileResource;
+ }
+}
\ No newline at end of file
diff --git a/Penumbra/Api/IpcLaunchingProvider.cs b/Penumbra/Api/IpcLaunchingProvider.cs
deleted file mode 100644
index ff851003..00000000
--- a/Penumbra/Api/IpcLaunchingProvider.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Dalamud.Plugin;
-using OtterGui.Log;
-using OtterGui.Services;
-using Penumbra.Api.Api;
-using Serilog.Events;
-
-namespace Penumbra.Api;
-
-public sealed class IpcLaunchingProvider : IApiService
-{
- public IpcLaunchingProvider(IDalamudPluginInterface pi, Logger log)
- {
- try
- {
- using var subscriber = log.MainLogger.IsEnabled(LogEventLevel.Debug)
- ? IpcSubscribers.Launching.Subscriber(pi,
- (major, minor) => log.Debug($"[IPC] Invoked Penumbra.Launching IPC with API Version {major}.{minor}."))
- : null;
-
- using var provider = IpcSubscribers.Launching.Provider(pi);
- provider.Invoke(PenumbraApi.BreakingVersion, PenumbraApi.FeatureVersion);
- }
- catch (Exception ex)
- {
- log.Error($"[IPC] Could not invoke Penumbra.Launching IPC:\n{ex}");
- }
- }
-}
diff --git a/Penumbra/Api/IpcProviders.cs b/Penumbra/Api/IpcProviders.cs
deleted file mode 100644
index 7cbe29f6..00000000
--- a/Penumbra/Api/IpcProviders.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-using Dalamud.Plugin;
-using OtterGui.Services;
-using Penumbra.Api.Api;
-using Penumbra.Api.Helpers;
-using Penumbra.Communication;
-using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
-
-namespace Penumbra.Api;
-
-public sealed class IpcProviders : IDisposable, IApiService
-{
- private readonly List _providers;
-
- private readonly EventProvider _disposedProvider;
- private readonly EventProvider _initializedProvider;
- private readonly CharacterUtility _characterUtility;
-
- public IpcProviders(IDalamudPluginInterface pi, IPenumbraApi api, CharacterUtility characterUtility)
- {
- _characterUtility = characterUtility;
- _disposedProvider = IpcSubscribers.Disposed.Provider(pi);
- _initializedProvider = IpcSubscribers.Initialized.Provider(pi);
- _providers =
- [
- IpcSubscribers.GetCollections.Provider(pi, api.Collection),
- IpcSubscribers.GetCollectionsByIdentifier.Provider(pi, api.Collection),
- IpcSubscribers.GetChangedItemsForCollection.Provider(pi, api.Collection),
- IpcSubscribers.GetCollection.Provider(pi, api.Collection),
- IpcSubscribers.GetCollectionForObject.Provider(pi, api.Collection),
- IpcSubscribers.SetCollection.Provider(pi, api.Collection),
- IpcSubscribers.SetCollectionForObject.Provider(pi, api.Collection),
- IpcSubscribers.CheckCurrentChangedItemFunc.Provider(pi, api.Collection),
-
- IpcSubscribers.ConvertTextureFile.Provider(pi, api.Editing),
- IpcSubscribers.ConvertTextureData.Provider(pi, api.Editing),
-
- IpcSubscribers.GetDrawObjectInfo.Provider(pi, api.GameState),
- IpcSubscribers.GetCutsceneParentIndex.Provider(pi, api.GameState),
- IpcSubscribers.SetCutsceneParentIndex.Provider(pi, api.GameState),
- IpcSubscribers.CreatingCharacterBase.Provider(pi, api.GameState),
- IpcSubscribers.CreatedCharacterBase.Provider(pi, api.GameState),
- IpcSubscribers.GameObjectResourcePathResolved.Provider(pi, api.GameState),
- IpcSubscribers.GetCutsceneParentIndexFunc.Provider(pi, api.GameState),
- IpcSubscribers.GetGameObjectFromDrawObjectFunc.Provider(pi, api.GameState),
-
- IpcSubscribers.GetPlayerMetaManipulations.Provider(pi, api.Meta),
- IpcSubscribers.GetMetaManipulations.Provider(pi, api.Meta),
-
- IpcSubscribers.GetModList.Provider(pi, api.Mods),
- IpcSubscribers.InstallMod.Provider(pi, api.Mods),
- IpcSubscribers.ReloadMod.Provider(pi, api.Mods),
- IpcSubscribers.AddMod.Provider(pi, api.Mods),
- IpcSubscribers.DeleteMod.Provider(pi, api.Mods),
- IpcSubscribers.ModDeleted.Provider(pi, api.Mods),
- IpcSubscribers.ModAdded.Provider(pi, api.Mods),
- IpcSubscribers.ModMoved.Provider(pi, api.Mods),
- IpcSubscribers.CreatingPcp.Provider(pi, api.Mods),
- IpcSubscribers.ParsingPcp.Provider(pi, api.Mods),
- IpcSubscribers.GetModPath.Provider(pi, api.Mods),
- IpcSubscribers.SetModPath.Provider(pi, api.Mods),
- IpcSubscribers.GetChangedItems.Provider(pi, api.Mods),
- IpcSubscribers.GetChangedItemAdapterDictionary.Provider(pi, api.Mods),
- IpcSubscribers.GetChangedItemAdapterList.Provider(pi, api.Mods),
-
- IpcSubscribers.GetAvailableModSettings.Provider(pi, api.ModSettings),
- IpcSubscribers.GetCurrentModSettings.Provider(pi, api.ModSettings),
- IpcSubscribers.GetCurrentModSettingsWithTemp.Provider(pi, api.ModSettings),
- IpcSubscribers.GetAllModSettings.Provider(pi, api.ModSettings),
- IpcSubscribers.GetSettingsInAllCollections.Provider(pi, api.ModSettings),
- IpcSubscribers.TryInheritMod.Provider(pi, api.ModSettings),
- IpcSubscribers.TrySetMod.Provider(pi, api.ModSettings),
- IpcSubscribers.TrySetModPriority.Provider(pi, api.ModSettings),
- IpcSubscribers.TrySetModSetting.Provider(pi, api.ModSettings),
- IpcSubscribers.TrySetModSettings.Provider(pi, api.ModSettings),
- IpcSubscribers.ModSettingChanged.Provider(pi, api.ModSettings),
- IpcSubscribers.CopyModSettings.Provider(pi, api.ModSettings),
-
- IpcSubscribers.ApiVersion.Provider(pi, api),
- new FuncProvider<(int Major, int Minor)>(pi, "Penumbra.ApiVersions", () => api.ApiVersion), // backward compatibility
- new FuncProvider(pi, "Penumbra.ApiVersion", () => api.ApiVersion.Breaking), // backward compatibility
- IpcSubscribers.GetModDirectory.Provider(pi, api.PluginState),
- IpcSubscribers.GetConfiguration.Provider(pi, api.PluginState),
- IpcSubscribers.ModDirectoryChanged.Provider(pi, api.PluginState),
- IpcSubscribers.GetEnabledState.Provider(pi, api.PluginState),
- IpcSubscribers.EnabledChange.Provider(pi, api.PluginState),
- IpcSubscribers.SupportedFeatures.Provider(pi, api.PluginState),
- IpcSubscribers.CheckSupportedFeatures.Provider(pi, api.PluginState),
-
- IpcSubscribers.RedrawObject.Provider(pi, api.Redraw),
- IpcSubscribers.RedrawAll.Provider(pi, api.Redraw),
- IpcSubscribers.GameObjectRedrawn.Provider(pi, api.Redraw),
- IpcSubscribers.RedrawCollectionMembers.Provider(pi, api.Redraw),
-
- IpcSubscribers.ResolveDefaultPath.Provider(pi, api.Resolve),
- IpcSubscribers.ResolveInterfacePath.Provider(pi, api.Resolve),
- IpcSubscribers.ResolveGameObjectPath.Provider(pi, api.Resolve),
- IpcSubscribers.ResolvePlayerPath.Provider(pi, api.Resolve),
- IpcSubscribers.ReverseResolveGameObjectPath.Provider(pi, api.Resolve),
- IpcSubscribers.ReverseResolvePlayerPath.Provider(pi, api.Resolve),
- IpcSubscribers.ResolvePlayerPaths.Provider(pi, api.Resolve),
- IpcSubscribers.ResolvePlayerPathsAsync.Provider(pi, api.Resolve),
- IpcSubscribers.ResolvePath.Provider(pi, api.Resolve),
- IpcSubscribers.ResolvePaths.Provider(pi, api.Resolve),
-
- IpcSubscribers.GetGameObjectResourcePaths.Provider(pi, api.ResourceTree),
- IpcSubscribers.GetPlayerResourcePaths.Provider(pi, api.ResourceTree),
- IpcSubscribers.GetGameObjectResourcesOfType.Provider(pi, api.ResourceTree),
- IpcSubscribers.GetPlayerResourcesOfType.Provider(pi, api.ResourceTree),
- IpcSubscribers.GetGameObjectResourceTrees.Provider(pi, api.ResourceTree),
- IpcSubscribers.GetPlayerResourceTrees.Provider(pi, api.ResourceTree),
-
- IpcSubscribers.CreateTemporaryCollection.Provider(pi, api.Temporary),
- IpcSubscribers.DeleteTemporaryCollection.Provider(pi, api.Temporary),
- IpcSubscribers.AssignTemporaryCollection.Provider(pi, api.Temporary),
- IpcSubscribers.AddTemporaryModAll.Provider(pi, api.Temporary),
- IpcSubscribers.AddTemporaryMod.Provider(pi, api.Temporary),
- IpcSubscribers.RemoveTemporaryModAll.Provider(pi, api.Temporary),
- IpcSubscribers.RemoveTemporaryMod.Provider(pi, api.Temporary),
- IpcSubscribers.SetTemporaryModSettings.Provider(pi, api.Temporary),
- IpcSubscribers.SetTemporaryModSettingsPlayer.Provider(pi, api.Temporary),
- IpcSubscribers.RemoveTemporaryModSettings.Provider(pi, api.Temporary),
- IpcSubscribers.RemoveTemporaryModSettingsPlayer.Provider(pi, api.Temporary),
- IpcSubscribers.RemoveAllTemporaryModSettings.Provider(pi, api.Temporary),
- IpcSubscribers.RemoveAllTemporaryModSettingsPlayer.Provider(pi, api.Temporary),
- IpcSubscribers.QueryTemporaryModSettings.Provider(pi, api.Temporary),
- IpcSubscribers.QueryTemporaryModSettingsPlayer.Provider(pi, api.Temporary),
-
- IpcSubscribers.ChangedItemTooltip.Provider(pi, api.Ui),
- IpcSubscribers.ChangedItemClicked.Provider(pi, api.Ui),
- IpcSubscribers.PreSettingsTabBarDraw.Provider(pi, api.Ui),
- IpcSubscribers.PreSettingsDraw.Provider(pi, api.Ui),
- IpcSubscribers.PostEnabledDraw.Provider(pi, api.Ui),
- IpcSubscribers.PostSettingsDraw.Provider(pi, api.Ui),
- IpcSubscribers.OpenMainWindow.Provider(pi, api.Ui),
- IpcSubscribers.CloseMainWindow.Provider(pi, api.Ui),
- IpcSubscribers.RegisterSettingsSection.Provider(pi, api.Ui),
- IpcSubscribers.UnregisterSettingsSection.Provider(pi, api.Ui),
- ];
- if (_characterUtility.Ready)
- _initializedProvider.Invoke();
- else
- _characterUtility.LoadingFinished.Subscribe(OnCharacterUtilityReady, CharacterUtilityFinished.Priority.IpcProvider);
- }
-
- private void OnCharacterUtilityReady()
- {
- _initializedProvider.Invoke();
- _characterUtility.LoadingFinished.Unsubscribe(OnCharacterUtilityReady);
- }
-
- public void Dispose()
- {
- _characterUtility.LoadingFinished.Unsubscribe(OnCharacterUtilityReady);
- foreach (var provider in _providers)
- provider.Dispose();
- _providers.Clear();
- _initializedProvider.Dispose();
- _disposedProvider.Invoke();
- _disposedProvider.Dispose();
- }
-}
diff --git a/Penumbra/Api/IpcTester/CollectionsIpcTester.cs b/Penumbra/Api/IpcTester/CollectionsIpcTester.cs
deleted file mode 100644
index f033b7c3..00000000
--- a/Penumbra/Api/IpcTester/CollectionsIpcTester.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Interface;
-using Dalamud.Interface.Utility;
-using Dalamud.Plugin;
-using OtterGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.Collections.Manager;
-using Penumbra.GameData.Data;
-using ImGuiClip = OtterGui.ImGuiClip;
-
-namespace Penumbra.Api.IpcTester;
-
-public class CollectionsIpcTester(IDalamudPluginInterface pi) : IUiService
-{
- private int _objectIdx;
- private string _collectionIdString = string.Empty;
- private Guid? _collectionId;
- private bool _allowCreation = true;
- private bool _allowDeletion = true;
- private ApiCollectionType _type = ApiCollectionType.Yourself;
-
- private Dictionary _collections = [];
- private (string, ChangedItemType, uint)[] _changedItems = [];
- private PenumbraApiEc _returnCode = PenumbraApiEc.Success;
- private (Guid Id, string Name)? _oldCollection;
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Collections");
- if (!_)
- return;
-
- ImGuiUtil.GenericEnumCombo("Collection Type", 200, _type, out _type, t => ((CollectionType)t).ToName());
- ImGui.InputInt("Object Index##Collections", ref _objectIdx, 0, 0);
- ImGuiUtil.GuidInput("Collection Id##Collections", "Collection Identifier...", string.Empty, ref _collectionId, ref _collectionIdString);
- ImGui.Checkbox("Allow Assignment Creation", ref _allowCreation);
- ImGui.SameLine();
- ImGui.Checkbox("Allow Assignment Deletion", ref _allowDeletion);
-
- using var table = ImRaii.Table(string.Empty, 4, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro("Last Return Code", _returnCode.ToString());
- if (_oldCollection != null)
- ImGui.TextUnformatted(!_oldCollection.HasValue ? "Created" : _oldCollection.ToString());
-
- IpcTester.DrawIntro(GetCollectionsByIdentifier.Label, "Collection Identifier");
- var collectionList = new GetCollectionsByIdentifier(pi).Invoke(_collectionIdString);
- if (collectionList.Count == 0)
- {
- DrawCollection(null);
- }
- else
- {
- DrawCollection(collectionList[0]);
- foreach (var pair in collectionList.Skip(1))
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- ImGui.TableNextColumn();
- ImGui.TableNextColumn();
- DrawCollection(pair);
- }
- }
-
- IpcTester.DrawIntro(GetCollection.Label, "Current Collection");
- DrawCollection(new GetCollection(pi).Invoke(ApiCollectionType.Current));
-
- IpcTester.DrawIntro(GetCollection.Label, "Default Collection");
- DrawCollection(new GetCollection(pi).Invoke(ApiCollectionType.Default));
-
- IpcTester.DrawIntro(GetCollection.Label, "Interface Collection");
- DrawCollection(new GetCollection(pi).Invoke(ApiCollectionType.Interface));
-
- IpcTester.DrawIntro(GetCollection.Label, "Special Collection");
- DrawCollection(new GetCollection(pi).Invoke(_type));
-
- IpcTester.DrawIntro(GetCollections.Label, "Collections");
- DrawCollectionPopup();
- if (ImGui.Button("Get##Collections"))
- {
- _collections = new GetCollections(pi).Invoke();
- ImGui.OpenPopup("Collections");
- }
-
- IpcTester.DrawIntro(GetCollectionForObject.Label, "Get Object Collection");
- var (valid, individual, effectiveCollection) = new GetCollectionForObject(pi).Invoke(_objectIdx);
- DrawCollection(effectiveCollection);
- ImGui.SameLine();
- ImGui.TextUnformatted($"({(valid ? "Valid" : "Invalid")} Object{(individual ? ", Individual Assignment)" : ")")}");
-
- IpcTester.DrawIntro(SetCollection.Label, "Set Special Collection");
- if (ImGui.Button("Set##SpecialCollection"))
- (_returnCode, _oldCollection) =
- new SetCollection(pi).Invoke(_type, _collectionId.GetValueOrDefault(Guid.Empty), _allowCreation, _allowDeletion);
- ImGui.TableNextColumn();
- if (ImGui.Button("Remove##SpecialCollection"))
- (_returnCode, _oldCollection) = new SetCollection(pi).Invoke(_type, null, _allowCreation, _allowDeletion);
-
- IpcTester.DrawIntro(SetCollectionForObject.Label, "Set Object Collection");
- if (ImGui.Button("Set##ObjectCollection"))
- (_returnCode, _oldCollection) = new SetCollectionForObject(pi).Invoke(_objectIdx, _collectionId.GetValueOrDefault(Guid.Empty),
- _allowCreation, _allowDeletion);
- ImGui.TableNextColumn();
- if (ImGui.Button("Remove##ObjectCollection"))
- (_returnCode, _oldCollection) = new SetCollectionForObject(pi).Invoke(_objectIdx, null, _allowCreation, _allowDeletion);
-
- IpcTester.DrawIntro(GetChangedItemsForCollection.Label, "Changed Item List");
- DrawChangedItemPopup();
- if (ImGui.Button("Get##ChangedItems"))
- {
- var items = new GetChangedItemsForCollection(pi).Invoke(_collectionId.GetValueOrDefault(Guid.Empty));
- _changedItems = items.Select(kvp =>
- {
- var (type, id) = kvp.Value.ToApiObject();
- return (kvp.Key, type, id);
- }).ToArray();
- ImGui.OpenPopup("Changed Item List");
- }
- IpcTester.DrawIntro(RedrawCollectionMembers.Label, "Redraw Collection Members");
- if (ImGui.Button("Redraw##ObjectCollection"))
- new RedrawCollectionMembers(pi).Invoke(collectionList[0].Id, RedrawType.Redraw);
-
- }
-
- private void DrawChangedItemPopup()
- {
- ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(500, 500));
- using var p = ImRaii.Popup("Changed Item List");
- if (!p)
- return;
-
- using (var table = ImRaii.Table("##ChangedItems", 3, ImGuiTableFlags.SizingFixedFit))
- {
- if (table)
- ImGuiClip.ClippedDraw(_changedItems, t =>
- {
- ImGuiUtil.DrawTableColumn(t.Item1);
- ImGuiUtil.DrawTableColumn(t.Item2.ToString());
- ImGuiUtil.DrawTableColumn(t.Item3.ToString());
- }, ImGui.GetTextLineHeightWithSpacing());
- }
-
- if (ImGui.Button("Close", -Vector2.UnitX) || !ImGui.IsWindowFocused())
- ImGui.CloseCurrentPopup();
- }
-
- private void DrawCollectionPopup()
- {
- ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(500, 500));
- using var p = ImRaii.Popup("Collections");
- if (!p)
- return;
-
- using (var t = ImRaii.Table("collections", 2, ImGuiTableFlags.SizingFixedFit))
- {
- if (t)
- foreach (var collection in _collections)
- {
- ImGui.TableNextColumn();
- DrawCollection((collection.Key, collection.Value));
- }
- }
-
- if (ImGui.Button("Close", -Vector2.UnitX) || !ImGui.IsWindowFocused())
- ImGui.CloseCurrentPopup();
- }
-
- private static void DrawCollection((Guid Id, string Name)? collection)
- {
- if (collection == null)
- {
- ImGui.TextUnformatted("");
- ImGui.TableNextColumn();
- return;
- }
-
- ImGui.TextUnformatted(collection.Value.Name);
- ImGui.TableNextColumn();
- using (ImRaii.PushFont(UiBuilder.MonoFont))
- {
- ImGuiUtil.CopyOnClickSelectable(collection.Value.Id.ToString());
- }
- }
-}
diff --git a/Penumbra/Api/IpcTester/EditingIpcTester.cs b/Penumbra/Api/IpcTester/EditingIpcTester.cs
deleted file mode 100644
index d754cf90..00000000
--- a/Penumbra/Api/IpcTester/EditingIpcTester.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Plugin;
-using OtterGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.IpcSubscribers;
-
-namespace Penumbra.Api.IpcTester;
-
-public class EditingIpcTester(IDalamudPluginInterface pi) : IUiService
-{
- private string _inputPath = string.Empty;
- private string _inputPath2 = string.Empty;
- private string _outputPath = string.Empty;
- private string _outputPath2 = string.Empty;
-
- private TextureType _typeSelector;
- private bool _mipMaps = true;
-
- private Task? _task1;
- private Task? _task2;
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Editing");
- if (!_)
- return;
-
- ImGui.InputTextWithHint("##inputPath", "Input Texture Path...", ref _inputPath, 256);
- ImGui.InputTextWithHint("##outputPath", "Output Texture Path...", ref _outputPath, 256);
- ImGui.InputTextWithHint("##inputPath2", "Input Texture Path 2...", ref _inputPath2, 256);
- ImGui.InputTextWithHint("##outputPath2", "Output Texture Path 2...", ref _outputPath2, 256);
- TypeCombo();
- ImGui.Checkbox("Add MipMaps", ref _mipMaps);
-
- using var table = ImRaii.Table("...", 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(ConvertTextureFile.Label, (string)"Convert Texture 1");
- if (ImGuiUtil.DrawDisabledButton("Save 1", Vector2.Zero, string.Empty, _task1 is { IsCompleted: false }))
- _task1 = new ConvertTextureFile(pi).Invoke(_inputPath, _outputPath, _typeSelector, _mipMaps);
- ImGui.SameLine();
- ImGui.TextUnformatted(_task1 == null ? "Not Initiated" : _task1.Status.ToString());
- if (ImGui.IsItemHovered() && _task1?.Status == TaskStatus.Faulted)
- ImGui.SetTooltip(_task1.Exception?.ToString());
-
- IpcTester.DrawIntro(ConvertTextureFile.Label, (string)"Convert Texture 2");
- if (ImGuiUtil.DrawDisabledButton("Save 2", Vector2.Zero, string.Empty, _task2 is { IsCompleted: false }))
- _task2 = new ConvertTextureFile(pi).Invoke(_inputPath2, _outputPath2, _typeSelector, _mipMaps);
- ImGui.SameLine();
- ImGui.TextUnformatted(_task2 == null ? "Not Initiated" : _task2.Status.ToString());
- if (ImGui.IsItemHovered() && _task2?.Status == TaskStatus.Faulted)
- ImGui.SetTooltip(_task2.Exception?.ToString());
- }
-
- private void TypeCombo()
- {
- using var combo = ImRaii.Combo("Convert To", _typeSelector.ToString());
- if (!combo)
- return;
-
- foreach (var value in Enum.GetValues())
- {
- if (ImGui.Selectable(value.ToString(), _typeSelector == value))
- _typeSelector = value;
- }
- }
-}
diff --git a/Penumbra/Api/IpcTester/GameStateIpcTester.cs b/Penumbra/Api/IpcTester/GameStateIpcTester.cs
deleted file mode 100644
index 38a09714..00000000
--- a/Penumbra/Api/IpcTester/GameStateIpcTester.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Interface;
-using Dalamud.Plugin;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.String;
-
-namespace Penumbra.Api.IpcTester;
-
-public class GameStateIpcTester : IUiService, IDisposable
-{
- private readonly IDalamudPluginInterface _pi;
- public readonly EventSubscriber CharacterBaseCreating;
- public readonly EventSubscriber CharacterBaseCreated;
- public readonly EventSubscriber GameObjectResourcePathResolved;
-
- private string _lastCreatedGameObjectName = string.Empty;
- private nint _lastCreatedDrawObject = nint.Zero;
- private DateTimeOffset _lastCreatedGameObjectTime = DateTimeOffset.MaxValue;
- private string _lastResolvedGamePath = string.Empty;
- private string _lastResolvedFullPath = string.Empty;
- private string _lastResolvedObject = string.Empty;
- private DateTimeOffset _lastResolvedGamePathTime = DateTimeOffset.MaxValue;
- private string _currentDrawObjectString = string.Empty;
- private nint _currentDrawObject = nint.Zero;
- private int _currentCutsceneActor;
- private int _currentCutsceneParent;
- private PenumbraApiEc _cutsceneError = PenumbraApiEc.Success;
-
- public GameStateIpcTester(IDalamudPluginInterface pi)
- {
- _pi = pi;
- CharacterBaseCreating = IpcSubscribers.CreatingCharacterBase.Subscriber(pi, UpdateLastCreated);
- CharacterBaseCreated = IpcSubscribers.CreatedCharacterBase.Subscriber(pi, UpdateLastCreated2);
- GameObjectResourcePathResolved = IpcSubscribers.GameObjectResourcePathResolved.Subscriber(pi, UpdateGameObjectResourcePath);
- CharacterBaseCreating.Disable();
- CharacterBaseCreated.Disable();
- GameObjectResourcePathResolved.Disable();
- }
-
- public void Dispose()
- {
- CharacterBaseCreating.Dispose();
- CharacterBaseCreated.Dispose();
- GameObjectResourcePathResolved.Dispose();
- }
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Game State");
- if (!_)
- return;
-
- if (ImGui.InputTextWithHint("##drawObject", "Draw Object Address..", ref _currentDrawObjectString, 16,
- ImGuiInputTextFlags.CharsHexadecimal))
- _currentDrawObject = nint.TryParse(_currentDrawObjectString, NumberStyles.HexNumber, CultureInfo.InvariantCulture,
- out var tmp)
- ? tmp
- : nint.Zero;
-
- ImGui.InputInt("Cutscene Actor", ref _currentCutsceneActor, 0);
- ImGui.InputInt("Cutscene Parent", ref _currentCutsceneParent, 0);
- if (_cutsceneError is not PenumbraApiEc.Success)
- {
- ImGui.SameLine();
- ImGui.TextUnformatted("Invalid Argument on last Call");
- }
-
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(GetDrawObjectInfo.Label, "Draw Object Info");
- if (_currentDrawObject == nint.Zero)
- {
- ImGui.TextUnformatted("Invalid");
- }
- else
- {
- var (ptr, (collectionId, collectionName)) = new GetDrawObjectInfo(_pi).Invoke(_currentDrawObject);
- ImGui.TextUnformatted(ptr == nint.Zero ? $"No Actor Associated, {collectionName}" : $"{ptr:X}, {collectionName}");
- ImGui.SameLine();
- using (ImRaii.PushFont(UiBuilder.MonoFont))
- {
- ImGui.TextUnformatted(collectionId.ToString());
- }
- }
-
- IpcTester.DrawIntro(GetCutsceneParentIndex.Label, "Cutscene Parent");
- ImGui.TextUnformatted(new GetCutsceneParentIndex(_pi).Invoke(_currentCutsceneActor).ToString());
-
- IpcTester.DrawIntro(SetCutsceneParentIndex.Label, "Cutscene Parent");
- if (ImGui.Button("Set Parent"))
- _cutsceneError = new SetCutsceneParentIndex(_pi)
- .Invoke(_currentCutsceneActor, _currentCutsceneParent);
-
- IpcTester.DrawIntro(CreatingCharacterBase.Label, "Last Drawobject created");
- if (_lastCreatedGameObjectTime < DateTimeOffset.Now)
- ImGui.TextUnformatted(_lastCreatedDrawObject != nint.Zero
- ? $"0x{_lastCreatedDrawObject:X} for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}"
- : $"NULL for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}");
-
- IpcTester.DrawIntro(IpcSubscribers.GameObjectResourcePathResolved.Label, "Last GamePath resolved");
- if (_lastResolvedGamePathTime < DateTimeOffset.Now)
- ImGui.TextUnformatted(
- $"{_lastResolvedGamePath} -> {_lastResolvedFullPath} for <{_lastResolvedObject}> at {_lastResolvedGamePathTime}");
- }
-
- private void UpdateLastCreated(nint gameObject, Guid _, nint _2, nint _3, nint _4)
- {
- _lastCreatedGameObjectName = GetObjectName(gameObject);
- _lastCreatedGameObjectTime = DateTimeOffset.Now;
- _lastCreatedDrawObject = nint.Zero;
- }
-
- private void UpdateLastCreated2(nint gameObject, Guid _, nint drawObject)
- {
- _lastCreatedGameObjectName = GetObjectName(gameObject);
- _lastCreatedGameObjectTime = DateTimeOffset.Now;
- _lastCreatedDrawObject = drawObject;
- }
-
- private void UpdateGameObjectResourcePath(nint gameObject, string gamePath, string fullPath)
- {
- _lastResolvedObject = GetObjectName(gameObject);
- _lastResolvedGamePath = gamePath;
- _lastResolvedFullPath = fullPath;
- _lastResolvedGamePathTime = DateTimeOffset.Now;
- }
-
- private static unsafe string GetObjectName(nint gameObject)
- {
- var obj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)gameObject;
- return obj != null && obj->Name[0] != 0 ? new ByteString(obj->Name).ToString() : "Unknown";
- }
-}
diff --git a/Penumbra/Api/IpcTester/IpcTester.cs b/Penumbra/Api/IpcTester/IpcTester.cs
deleted file mode 100644
index b03d7e03..00000000
--- a/Penumbra/Api/IpcTester/IpcTester.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.System.Framework;
-using Dalamud.Bindings.ImGui;
-using OtterGui.Services;
-using Penumbra.Api.Api;
-
-namespace Penumbra.Api.IpcTester;
-
-public class IpcTester(
- IpcProviders ipcProviders,
- IPenumbraApi api,
- PluginStateIpcTester pluginStateIpcTester,
- UiIpcTester uiIpcTester,
- RedrawingIpcTester redrawingIpcTester,
- GameStateIpcTester gameStateIpcTester,
- ResolveIpcTester resolveIpcTester,
- CollectionsIpcTester collectionsIpcTester,
- MetaIpcTester metaIpcTester,
- ModsIpcTester modsIpcTester,
- ModSettingsIpcTester modSettingsIpcTester,
- EditingIpcTester editingIpcTester,
- TemporaryIpcTester temporaryIpcTester,
- ResourceTreeIpcTester resourceTreeIpcTester,
- IFramework framework) : IUiService
-{
- private readonly IpcProviders _ipcProviders = ipcProviders;
- private DateTime _lastUpdate;
- private bool _subscribed = false;
-
- public void Draw()
- {
- try
- {
- _lastUpdate = framework.LastUpdateUTC.AddSeconds(1);
- Subscribe();
-
- ImGui.TextUnformatted($"API Version: {api.ApiVersion.Breaking}.{api.ApiVersion.Feature:D4}");
- collectionsIpcTester.Draw();
- editingIpcTester.Draw();
- gameStateIpcTester.Draw();
- metaIpcTester.Draw();
- modSettingsIpcTester.Draw();
- modsIpcTester.Draw();
- pluginStateIpcTester.Draw();
- redrawingIpcTester.Draw();
- resolveIpcTester.Draw();
- resourceTreeIpcTester.Draw();
- uiIpcTester.Draw();
- temporaryIpcTester.Draw();
- temporaryIpcTester.DrawCollections();
- temporaryIpcTester.DrawMods();
- }
- catch (Exception e)
- {
- Penumbra.Log.Error($"Error during IPC Tests:\n{e}");
- }
- }
-
- internal static void DrawIntro(string label, string info)
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(label);
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(info);
- ImGui.TableNextColumn();
- }
-
- private void Subscribe()
- {
- if (_subscribed)
- return;
-
- Penumbra.Log.Debug("[IPCTester] Subscribed to IPC events for IPC tester.");
- gameStateIpcTester.GameObjectResourcePathResolved.Enable();
- gameStateIpcTester.CharacterBaseCreated.Enable();
- gameStateIpcTester.CharacterBaseCreating.Enable();
- modSettingsIpcTester.SettingChanged.Enable();
- modsIpcTester.DeleteSubscriber.Enable();
- modsIpcTester.AddSubscriber.Enable();
- modsIpcTester.MoveSubscriber.Enable();
- pluginStateIpcTester.ModDirectoryChanged.Enable();
- pluginStateIpcTester.Initialized.Enable();
- pluginStateIpcTester.Disposed.Enable();
- pluginStateIpcTester.EnabledChange.Enable();
- redrawingIpcTester.Redrawn.Enable();
- uiIpcTester.PreSettingsTabBar.Enable();
- uiIpcTester.PreSettingsPanel.Enable();
- uiIpcTester.PostEnabled.Enable();
- uiIpcTester.PostSettingsPanelDraw.Enable();
- uiIpcTester.ChangedItemTooltip.Enable();
- uiIpcTester.ChangedItemClicked.Enable();
-
- framework.Update += CheckUnsubscribe;
- _subscribed = true;
- }
-
- private void CheckUnsubscribe(IFramework framework1)
- {
- if (_lastUpdate > framework.LastUpdateUTC)
- return;
-
- Unsubscribe();
- framework.Update -= CheckUnsubscribe;
- }
-
- private void Unsubscribe()
- {
- if (!_subscribed)
- return;
-
- Penumbra.Log.Debug("[IPCTester] Unsubscribed from IPC events for IPC tester.");
- _subscribed = false;
- gameStateIpcTester.GameObjectResourcePathResolved.Disable();
- gameStateIpcTester.CharacterBaseCreated.Disable();
- gameStateIpcTester.CharacterBaseCreating.Disable();
- modSettingsIpcTester.SettingChanged.Disable();
- modsIpcTester.DeleteSubscriber.Disable();
- modsIpcTester.AddSubscriber.Disable();
- modsIpcTester.MoveSubscriber.Disable();
- pluginStateIpcTester.ModDirectoryChanged.Disable();
- pluginStateIpcTester.Initialized.Disable();
- pluginStateIpcTester.Disposed.Disable();
- pluginStateIpcTester.EnabledChange.Disable();
- redrawingIpcTester.Redrawn.Disable();
- uiIpcTester.PreSettingsTabBar.Disable();
- uiIpcTester.PreSettingsPanel.Disable();
- uiIpcTester.PostEnabled.Disable();
- uiIpcTester.PostSettingsPanelDraw.Disable();
- uiIpcTester.ChangedItemTooltip.Disable();
- uiIpcTester.ChangedItemClicked.Disable();
- }
-}
diff --git a/Penumbra/Api/IpcTester/MetaIpcTester.cs b/Penumbra/Api/IpcTester/MetaIpcTester.cs
deleted file mode 100644
index bee1981c..00000000
--- a/Penumbra/Api/IpcTester/MetaIpcTester.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Plugin;
-using OtterGui.Raii;
-using OtterGui.Services;
-using OtterGui.Text;
-using Penumbra.Api.Api;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.Meta.Manipulations;
-
-namespace Penumbra.Api.IpcTester;
-
-public class MetaIpcTester(IDalamudPluginInterface pi) : IUiService
-{
- private int _gameObjectIndex;
- private string _metaBase64 = string.Empty;
- private MetaDictionary _metaDict = new();
- private byte _parsedVersion = byte.MaxValue;
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Meta");
- if (!_)
- return;
-
- ImGui.InputInt("##metaIdx", ref _gameObjectIndex, 0, 0);
- if (ImUtf8.InputText("##metaText"u8, ref _metaBase64, "Base64 Metadata..."u8))
- if (!MetaApi.ConvertManips(_metaBase64, out _metaDict!, out _parsedVersion))
- _metaDict ??= new MetaDictionary();
-
-
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(GetPlayerMetaManipulations.Label, "Player Meta Manipulations");
- if (ImGui.Button("Copy to Clipboard##Player"))
- {
- var base64 = new GetPlayerMetaManipulations(pi).Invoke();
- ImGui.SetClipboardText(base64);
- }
-
- IpcTester.DrawIntro(GetMetaManipulations.Label, "Game Object Manipulations");
- if (ImGui.Button("Copy to Clipboard##GameObject"))
- {
- var base64 = new GetMetaManipulations(pi).Invoke(_gameObjectIndex);
- ImGui.SetClipboardText(base64);
- }
-
- IpcTester.DrawIntro(string.Empty, "Parsed Data");
- ImUtf8.Text($"Version: {_parsedVersion}, Count: {_metaDict.Count}");
- }
-}
diff --git a/Penumbra/Api/IpcTester/ModSettingsIpcTester.cs b/Penumbra/Api/IpcTester/ModSettingsIpcTester.cs
deleted file mode 100644
index 152efa45..00000000
--- a/Penumbra/Api/IpcTester/ModSettingsIpcTester.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Plugin;
-using OtterGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using OtterGui.Text;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.UI;
-
-namespace Penumbra.Api.IpcTester;
-
-public class ModSettingsIpcTester : IUiService, IDisposable
-{
- private readonly IDalamudPluginInterface _pi;
- public readonly EventSubscriber SettingChanged;
-
- private PenumbraApiEc _lastSettingsError = PenumbraApiEc.Success;
- private ModSettingChange _lastSettingChangeType;
- private Guid _lastSettingChangeCollection = Guid.Empty;
- private string _lastSettingChangeMod = string.Empty;
- private bool _lastSettingChangeInherited;
- private DateTimeOffset _lastSettingChange;
-
- private string _settingsModDirectory = string.Empty;
- private string _settingsModName = string.Empty;
- private Guid? _settingsCollection;
- private string _settingsCollectionName = string.Empty;
- private bool _settingsIgnoreInheritance;
- private bool _settingsIgnoreTemporary;
- private int _settingsKey;
- private bool _settingsInherit;
- private bool _settingsTemporary;
- private bool _settingsEnabled;
- private int _settingsPriority;
- private IReadOnlyDictionary? _availableSettings;
- private Dictionary>? _currentSettings;
- private Dictionary>, bool, bool)>? _allSettings;
-
- public ModSettingsIpcTester(IDalamudPluginInterface pi)
- {
- _pi = pi;
- SettingChanged = ModSettingChanged.Subscriber(pi, UpdateLastModSetting);
- SettingChanged.Disable();
- }
-
- public void Dispose()
- {
- SettingChanged.Dispose();
- }
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Mod Settings");
- if (!_)
- return;
-
- ImGui.InputTextWithHint("##settingsDir", "Mod Directory Name...", ref _settingsModDirectory, 100);
- ImGui.InputTextWithHint("##settingsName", "Mod Name...", ref _settingsModName, 100);
- ImGuiUtil.GuidInput("##settingsCollection", "Collection...", string.Empty, ref _settingsCollection, ref _settingsCollectionName);
- ImUtf8.Checkbox("Ignore Inheritance"u8, ref _settingsIgnoreInheritance);
- ImUtf8.Checkbox("Ignore Temporary"u8, ref _settingsIgnoreTemporary);
- ImUtf8.InputScalar("Key"u8, ref _settingsKey);
- var collection = _settingsCollection.GetValueOrDefault(Guid.Empty);
-
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro("Last Error", _lastSettingsError.ToString());
-
- IpcTester.DrawIntro(ModSettingChanged.Label, "Last Mod Setting Changed");
- ImGui.TextUnformatted(_lastSettingChangeMod.Length > 0
- ? $"{_lastSettingChangeType} of {_lastSettingChangeMod} in {_lastSettingChangeCollection}{(_lastSettingChangeInherited ? " (Inherited)" : string.Empty)} at {_lastSettingChange}"
- : "None");
-
- IpcTester.DrawIntro(GetAvailableModSettings.Label, "Get Available Settings");
- if (ImGui.Button("Get##Available"))
- {
- _availableSettings = new GetAvailableModSettings(_pi).Invoke(_settingsModDirectory, _settingsModName);
- _lastSettingsError = _availableSettings == null ? PenumbraApiEc.ModMissing : PenumbraApiEc.Success;
- }
-
- IpcTester.DrawIntro(GetCurrentModSettings.Label, "Get Current Settings");
- if (ImGui.Button("Get##Current"))
- {
- var ret = new GetCurrentModSettings(_pi)
- .Invoke(collection, _settingsModDirectory, _settingsModName, _settingsIgnoreInheritance);
- _lastSettingsError = ret.Item1;
- if (ret.Item1 == PenumbraApiEc.Success)
- {
- _settingsEnabled = ret.Item2?.Item1 ?? false;
- _settingsInherit = ret.Item2?.Item4 ?? true;
- _settingsTemporary = false;
- _settingsPriority = ret.Item2?.Item2 ?? 0;
- _currentSettings = ret.Item2?.Item3;
- }
- else
- {
- _currentSettings = null;
- }
- }
-
- IpcTester.DrawIntro(GetCurrentModSettingsWithTemp.Label, "Get Current Settings With Temp");
- if (ImGui.Button("Get##CurrentTemp"))
- {
- var ret = new GetCurrentModSettingsWithTemp(_pi)
- .Invoke(collection, _settingsModDirectory, _settingsModName, _settingsIgnoreInheritance, _settingsIgnoreTemporary, _settingsKey);
- _lastSettingsError = ret.Item1;
- if (ret.Item1 == PenumbraApiEc.Success)
- {
- _settingsEnabled = ret.Item2?.Item1 ?? false;
- _settingsInherit = ret.Item2?.Item4 ?? true;
- _settingsTemporary = ret.Item2?.Item5 ?? false;
- _settingsPriority = ret.Item2?.Item2 ?? 0;
- _currentSettings = ret.Item2?.Item3;
- }
- else
- {
- _currentSettings = null;
- }
- }
-
- IpcTester.DrawIntro(GetAllModSettings.Label, "Get All Mod Settings");
- if (ImGui.Button("Get##All"))
- {
- var ret = new GetAllModSettings(_pi).Invoke(collection, _settingsIgnoreInheritance, _settingsIgnoreTemporary, _settingsKey);
- _lastSettingsError = ret.Item1;
- _allSettings = ret.Item2;
- }
-
- if (_allSettings != null)
- {
- ImGui.SameLine();
- ImUtf8.Text($"{_allSettings.Count} Mods");
- }
-
- IpcTester.DrawIntro(TryInheritMod.Label, "Inherit Mod");
- ImGui.Checkbox("##inherit", ref _settingsInherit);
- ImGui.SameLine();
- if (ImGui.Button("Set##Inherit"))
- _lastSettingsError = new TryInheritMod(_pi)
- .Invoke(collection, _settingsModDirectory, _settingsInherit, _settingsModName);
-
- IpcTester.DrawIntro(TrySetMod.Label, "Set Enabled");
- ImGui.Checkbox("##enabled", ref _settingsEnabled);
- ImGui.SameLine();
- if (ImGui.Button("Set##Enabled"))
- _lastSettingsError = new TrySetMod(_pi)
- .Invoke(collection, _settingsModDirectory, _settingsEnabled, _settingsModName);
-
- IpcTester.DrawIntro(TrySetModPriority.Label, "Set Priority");
- ImGui.SetNextItemWidth(200 * UiHelpers.Scale);
- ImGui.DragInt("##Priority", ref _settingsPriority);
- ImGui.SameLine();
- if (ImGui.Button("Set##Priority"))
- _lastSettingsError = new TrySetModPriority(_pi)
- .Invoke(collection, _settingsModDirectory, _settingsPriority, _settingsModName);
-
- IpcTester.DrawIntro(CopyModSettings.Label, "Copy Mod Settings");
- if (ImGui.Button("Copy Settings"))
- _lastSettingsError = new CopyModSettings(_pi)
- .Invoke(_settingsCollection, _settingsModDirectory, _settingsModName);
-
- ImGuiUtil.HoverTooltip("Copy settings from Mod Directory Name to Mod Name (as directory) in collection.");
-
- IpcTester.DrawIntro(TrySetModSetting.Label, "Set Setting(s)");
- if (_availableSettings == null)
- return;
-
- foreach (var (group, (list, type)) in _availableSettings)
- {
- using var id = ImRaii.PushId(group);
- var preview = list.Length > 0 ? list[0] : string.Empty;
- if (_currentSettings != null && _currentSettings.TryGetValue(group, out var current) && current.Count > 0)
- {
- preview = current[0];
- }
- else
- {
- current = [];
- if (_currentSettings != null)
- _currentSettings[group] = current;
- }
-
- ImGui.SetNextItemWidth(200 * UiHelpers.Scale);
- using (var c = ImRaii.Combo("##group", preview))
- {
- if (c)
- foreach (var s in list)
- {
- var contained = current.Contains(s);
- if (ImGui.Checkbox(s, ref contained))
- {
- if (contained)
- current.Add(s);
- else
- current.Remove(s);
- }
- }
- }
-
- ImGui.SameLine();
- if (ImGui.Button("Set##setting"))
- _lastSettingsError = type == GroupType.Single
- ? new TrySetModSetting(_pi).Invoke(collection, _settingsModDirectory, group, current.Count > 0 ? current[0] : string.Empty,
- _settingsModName)
- : new TrySetModSettings(_pi).Invoke(collection, _settingsModDirectory, group, current.ToArray(), _settingsModName);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(group);
- }
- }
-
- private void UpdateLastModSetting(ModSettingChange type, Guid collection, string mod, bool inherited)
- {
- _lastSettingChangeType = type;
- _lastSettingChangeCollection = collection;
- _lastSettingChangeMod = mod;
- _lastSettingChangeInherited = inherited;
- _lastSettingChange = DateTimeOffset.Now;
- }
-}
diff --git a/Penumbra/Api/IpcTester/ModsIpcTester.cs b/Penumbra/Api/IpcTester/ModsIpcTester.cs
deleted file mode 100644
index 9ea53366..00000000
--- a/Penumbra/Api/IpcTester/ModsIpcTester.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Interface.Utility;
-using Dalamud.Plugin;
-using OtterGui.Raii;
-using OtterGui.Services;
-using OtterGui.Text;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-
-namespace Penumbra.Api.IpcTester;
-
-public class ModsIpcTester : IUiService, IDisposable
-{
- private readonly IDalamudPluginInterface _pi;
-
- private string _modDirectory = string.Empty;
- private string _modName = string.Empty;
- private string _pathInput = string.Empty;
- private string _newInstallPath = string.Empty;
- private PenumbraApiEc _lastReloadEc;
- private PenumbraApiEc _lastAddEc;
- private PenumbraApiEc _lastDeleteEc;
- private PenumbraApiEc _lastSetPathEc;
- private PenumbraApiEc _lastInstallEc;
- private Dictionary _mods = [];
- private Dictionary _changedItems = [];
-
- public readonly EventSubscriber DeleteSubscriber;
- public readonly EventSubscriber AddSubscriber;
- public readonly EventSubscriber MoveSubscriber;
-
- private DateTimeOffset _lastDeletedModTime = DateTimeOffset.UnixEpoch;
- private string _lastDeletedMod = string.Empty;
- private DateTimeOffset _lastAddedModTime = DateTimeOffset.UnixEpoch;
- private string _lastAddedMod = string.Empty;
- private DateTimeOffset _lastMovedModTime = DateTimeOffset.UnixEpoch;
- private string _lastMovedModFrom = string.Empty;
- private string _lastMovedModTo = string.Empty;
-
- public ModsIpcTester(IDalamudPluginInterface pi)
- {
- _pi = pi;
- DeleteSubscriber = ModDeleted.Subscriber(pi, s =>
- {
- _lastDeletedModTime = DateTimeOffset.UtcNow;
- _lastDeletedMod = s;
- });
- AddSubscriber = ModAdded.Subscriber(pi, s =>
- {
- _lastAddedModTime = DateTimeOffset.UtcNow;
- _lastAddedMod = s;
- });
- MoveSubscriber = ModMoved.Subscriber(pi, (s1, s2) =>
- {
- _lastMovedModTime = DateTimeOffset.UtcNow;
- _lastMovedModFrom = s1;
- _lastMovedModTo = s2;
- });
- DeleteSubscriber.Disable();
- AddSubscriber.Disable();
- MoveSubscriber.Disable();
- }
-
- public void Dispose()
- {
- DeleteSubscriber.Dispose();
- DeleteSubscriber.Disable();
- AddSubscriber.Dispose();
- AddSubscriber.Disable();
- MoveSubscriber.Dispose();
- MoveSubscriber.Disable();
- }
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Mods");
- if (!_)
- return;
-
- ImGui.InputTextWithHint("##install", "Install File Path...", ref _newInstallPath, 100);
- ImGui.InputTextWithHint("##modDir", "Mod Directory Name...", ref _modDirectory, 100);
- ImGui.InputTextWithHint("##modName", "Mod Name...", ref _modName, 100);
- ImGui.InputTextWithHint("##path", "New Path...", ref _pathInput, 100);
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(GetModList.Label, "Mods");
- DrawModsPopup();
- if (ImGui.Button("Get##Mods"))
- {
- _mods = new GetModList(_pi).Invoke();
- ImGui.OpenPopup("Mods");
- }
-
- IpcTester.DrawIntro(ReloadMod.Label, "Reload Mod");
- if (ImGui.Button("Reload"))
- _lastReloadEc = new ReloadMod(_pi).Invoke(_modDirectory, _modName);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastReloadEc.ToString());
-
- IpcTester.DrawIntro(InstallMod.Label, "Install Mod");
- if (ImGui.Button("Install"))
- _lastInstallEc = new InstallMod(_pi).Invoke(_newInstallPath);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastInstallEc.ToString());
-
- IpcTester.DrawIntro(AddMod.Label, "Add Mod");
- if (ImGui.Button("Add"))
- _lastAddEc = new AddMod(_pi).Invoke(_modDirectory);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastAddEc.ToString());
-
- IpcTester.DrawIntro(DeleteMod.Label, "Delete Mod");
- if (ImGui.Button("Delete"))
- _lastDeleteEc = new DeleteMod(_pi).Invoke(_modDirectory, _modName);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastDeleteEc.ToString());
-
- IpcTester.DrawIntro(GetChangedItems.Label, "Get Changed Items");
- DrawChangedItemsPopup();
- if (ImUtf8.Button("Get##ChangedItems"u8))
- {
- _changedItems = new GetChangedItems(_pi).Invoke(_modDirectory, _modName);
- ImUtf8.OpenPopup("ChangedItems"u8);
- }
-
- IpcTester.DrawIntro(GetModPath.Label, "Current Path");
- var (ec, path, def, nameDef) = new GetModPath(_pi).Invoke(_modDirectory, _modName);
- ImGui.TextUnformatted($"{path} ({(def ? "Custom" : "Default")} Path, {(nameDef ? "Custom" : "Default")} Name) [{ec}]");
-
- IpcTester.DrawIntro(SetModPath.Label, "Set Path");
- if (ImGui.Button("Set"))
- _lastSetPathEc = new SetModPath(_pi).Invoke(_modDirectory, _pathInput, _modName);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastSetPathEc.ToString());
-
- IpcTester.DrawIntro(ModDeleted.Label, "Last Mod Deleted");
- if (_lastDeletedModTime > DateTimeOffset.UnixEpoch)
- ImGui.TextUnformatted($"{_lastDeletedMod} at {_lastDeletedModTime}");
-
- IpcTester.DrawIntro(ModAdded.Label, "Last Mod Added");
- if (_lastAddedModTime > DateTimeOffset.UnixEpoch)
- ImGui.TextUnformatted($"{_lastAddedMod} at {_lastAddedModTime}");
-
- IpcTester.DrawIntro(ModMoved.Label, "Last Mod Moved");
- if (_lastMovedModTime > DateTimeOffset.UnixEpoch)
- ImGui.TextUnformatted($"{_lastMovedModFrom} -> {_lastMovedModTo} at {_lastMovedModTime}");
- }
-
- private void DrawModsPopup()
- {
- ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(500, 500));
- using var p = ImRaii.Popup("Mods");
- if (!p)
- return;
-
- foreach (var (modDir, modName) in _mods)
- ImGui.TextUnformatted($"{modDir}: {modName}");
-
- if (ImGui.Button("Close", -Vector2.UnitX) || !ImGui.IsWindowFocused())
- ImGui.CloseCurrentPopup();
- }
-
- private void DrawChangedItemsPopup()
- {
- ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(500, 500));
- using var p = ImUtf8.Popup("ChangedItems"u8);
- if (!p)
- return;
-
- foreach (var (name, data) in _changedItems)
- ImUtf8.Text($"{name}: {data}");
-
- if (ImUtf8.Button("Close"u8, -Vector2.UnitX) || !ImGui.IsWindowFocused())
- ImGui.CloseCurrentPopup();
- }
-}
diff --git a/Penumbra/Api/IpcTester/PluginStateIpcTester.cs b/Penumbra/Api/IpcTester/PluginStateIpcTester.cs
deleted file mode 100644
index 073305d0..00000000
--- a/Penumbra/Api/IpcTester/PluginStateIpcTester.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-using Dalamud.Interface;
-using Dalamud.Interface.Utility;
-using Dalamud.Plugin;
-using Dalamud.Bindings.ImGui;
-using OtterGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using OtterGui.Text;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-
-namespace Penumbra.Api.IpcTester;
-
-public class PluginStateIpcTester : IUiService, IDisposable
-{
- private readonly IDalamudPluginInterface _pi;
- public readonly EventSubscriber ModDirectoryChanged;
- public readonly EventSubscriber Initialized;
- public readonly EventSubscriber Disposed;
- public readonly EventSubscriber EnabledChange;
-
- private string _currentConfiguration = string.Empty;
- private string _lastModDirectory = string.Empty;
- private bool _lastModDirectoryValid;
- private DateTimeOffset _lastModDirectoryTime = DateTimeOffset.MinValue;
-
- private readonly List _initializedList = [];
- private readonly List _disposedList = [];
-
- private string _requiredFeatureString = string.Empty;
- private string[] _requiredFeatures = [];
-
- private DateTimeOffset _lastEnabledChange = DateTimeOffset.UnixEpoch;
- private bool? _lastEnabledValue;
-
- public PluginStateIpcTester(IDalamudPluginInterface pi)
- {
- _pi = pi;
- ModDirectoryChanged = IpcSubscribers.ModDirectoryChanged.Subscriber(pi, UpdateModDirectoryChanged);
- Initialized = IpcSubscribers.Initialized.Subscriber(pi, AddInitialized);
- Disposed = IpcSubscribers.Disposed.Subscriber(pi, AddDisposed);
- EnabledChange = IpcSubscribers.EnabledChange.Subscriber(pi, SetLastEnabled);
- ModDirectoryChanged.Disable();
- EnabledChange.Disable();
- }
-
- public void Dispose()
- {
- ModDirectoryChanged.Dispose();
- Initialized.Dispose();
- Disposed.Dispose();
- EnabledChange.Dispose();
- }
-
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Plugin State");
- if (!_)
- return;
-
- if (ImUtf8.InputText("Required Features"u8, ref _requiredFeatureString))
- _requiredFeatures = _requiredFeatureString.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- DrawList(IpcSubscribers.Initialized.Label, "Last Initialized", _initializedList);
- DrawList(IpcSubscribers.Disposed.Label, "Last Disposed", _disposedList);
-
- IpcTester.DrawIntro(ApiVersion.Label, "Current Version");
- var (breaking, features) = new ApiVersion(_pi).Invoke();
- ImGui.TextUnformatted($"{breaking}.{features:D4}");
-
- IpcTester.DrawIntro(GetEnabledState.Label, "Current State");
- ImGui.TextUnformatted($"{new GetEnabledState(_pi).Invoke()}");
-
- IpcTester.DrawIntro(IpcSubscribers.EnabledChange.Label, "Last Change");
- ImGui.TextUnformatted(_lastEnabledValue is { } v ? $"{_lastEnabledChange} (to {v})" : "Never");
-
- IpcTester.DrawIntro(SupportedFeatures.Label, "Supported Features");
- ImUtf8.Text(string.Join(", ", new SupportedFeatures(_pi).Invoke()));
-
- IpcTester.DrawIntro(CheckSupportedFeatures.Label, "Missing Features");
- ImUtf8.Text(string.Join(", ", new CheckSupportedFeatures(_pi).Invoke(_requiredFeatures)));
-
- DrawConfigPopup();
- IpcTester.DrawIntro(GetConfiguration.Label, "Configuration");
- if (ImGui.Button("Get"))
- {
- _currentConfiguration = new GetConfiguration(_pi).Invoke();
- ImGui.OpenPopup("Config Popup");
- }
-
- IpcTester.DrawIntro(GetModDirectory.Label, "Current Mod Directory");
- ImGui.TextUnformatted(new GetModDirectory(_pi).Invoke());
-
- IpcTester.DrawIntro(IpcSubscribers.ModDirectoryChanged.Label, "Last Mod Directory Change");
- ImGui.TextUnformatted(_lastModDirectoryTime > DateTimeOffset.MinValue
- ? $"{_lastModDirectory} ({(_lastModDirectoryValid ? "Valid" : "Invalid")}) at {_lastModDirectoryTime}"
- : "None");
-
- void DrawList(string label, string text, List list)
- {
- IpcTester.DrawIntro(label, text);
- if (list.Count == 0)
- {
- ImGui.TextUnformatted("Never");
- }
- else
- {
- ImGui.TextUnformatted(list[^1].LocalDateTime.ToString(CultureInfo.CurrentCulture));
- if (list.Count > 1 && ImGui.IsItemHovered())
- ImGui.SetTooltip(string.Join("\n",
- list.SkipLast(1).Select(t => t.LocalDateTime.ToString(CultureInfo.CurrentCulture))));
- }
- }
- }
-
- private void DrawConfigPopup()
- {
- ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(500, 500));
- using var popup = ImRaii.Popup("Config Popup");
- if (!popup)
- return;
-
- using (ImRaii.PushFont(UiBuilder.MonoFont))
- {
- ImGuiUtil.TextWrapped(_currentConfiguration);
- }
-
- if (ImGui.Button("Close", -Vector2.UnitX) || !ImGui.IsWindowFocused())
- ImGui.CloseCurrentPopup();
- }
-
- private void UpdateModDirectoryChanged(string path, bool valid)
- => (_lastModDirectory, _lastModDirectoryValid, _lastModDirectoryTime) = (path, valid, DateTimeOffset.Now);
-
- private void AddInitialized()
- => _initializedList.Add(DateTimeOffset.UtcNow);
-
- private void AddDisposed()
- => _disposedList.Add(DateTimeOffset.UtcNow);
-
- private void SetLastEnabled(bool val)
- => (_lastEnabledChange, _lastEnabledValue) = (DateTimeOffset.Now, val);
-}
diff --git a/Penumbra/Api/IpcTester/RedrawingIpcTester.cs b/Penumbra/Api/IpcTester/RedrawingIpcTester.cs
deleted file mode 100644
index 6b853ed2..00000000
--- a/Penumbra/Api/IpcTester/RedrawingIpcTester.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using Dalamud.Plugin;
-using Dalamud.Plugin.Services;
-using Dalamud.Bindings.ImGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.GameData.Interop;
-using Penumbra.UI;
-
-namespace Penumbra.Api.IpcTester;
-
-public class RedrawingIpcTester : IUiService, IDisposable
-{
- private readonly IDalamudPluginInterface _pi;
- private readonly ObjectManager _objects;
- public readonly EventSubscriber Redrawn;
-
- private int _redrawIndex;
- private string _lastRedrawnString = "None";
-
- public RedrawingIpcTester(IDalamudPluginInterface pi, ObjectManager objects)
- {
- _pi = pi;
- _objects = objects;
- Redrawn = GameObjectRedrawn.Subscriber(_pi, SetLastRedrawn);
- Redrawn.Disable();
- }
-
- public void Dispose()
- {
- Redrawn.Dispose();
- }
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Redrawing");
- if (!_)
- return;
-
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(RedrawObject.Label, "Redraw by Index");
- var tmp = _redrawIndex;
- ImGui.SetNextItemWidth(100 * UiHelpers.Scale);
- if (ImGui.DragInt("##redrawIndex", ref tmp, 0.1f, 0, _objects.TotalCount))
- _redrawIndex = Math.Clamp(tmp, 0, _objects.TotalCount);
- ImGui.SameLine();
- if (ImGui.Button("Redraw##Index"))
- new RedrawObject(_pi).Invoke(_redrawIndex);
-
- IpcTester.DrawIntro(RedrawAll.Label, "Redraw All");
- if (ImGui.Button("Redraw##All"))
- new RedrawAll(_pi).Invoke();
-
- IpcTester.DrawIntro(GameObjectRedrawn.Label, "Last Redrawn Object:");
- ImGui.TextUnformatted(_lastRedrawnString);
- }
-
- private void SetLastRedrawn(nint address, int index)
- {
- if (index < 0
- || index > _objects.TotalCount
- || address == nint.Zero
- || _objects[index].Address != address)
- _lastRedrawnString = "Invalid";
-
- _lastRedrawnString = $"{_objects[index].Utf8Name} (0x{address:X}, {index})";
- }
-}
diff --git a/Penumbra/Api/IpcTester/ResolveIpcTester.cs b/Penumbra/Api/IpcTester/ResolveIpcTester.cs
deleted file mode 100644
index 9fc5bfc7..00000000
--- a/Penumbra/Api/IpcTester/ResolveIpcTester.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using Dalamud.Plugin;
-using Dalamud.Bindings.ImGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.String.Classes;
-
-namespace Penumbra.Api.IpcTester;
-
-public class ResolveIpcTester(IDalamudPluginInterface pi) : IUiService
-{
- private string _currentResolvePath = string.Empty;
- private string _currentReversePath = string.Empty;
- private int _currentReverseIdx;
- private Task<(string[], string[][])> _task = Task.FromResult<(string[], string[][])>(([], []));
-
- public void Draw()
- {
- using var tree = ImRaii.TreeNode("Resolving");
- if (!tree)
- return;
-
- ImGui.InputTextWithHint("##resolvePath", "Resolve this game path...", ref _currentResolvePath, Utf8GamePath.MaxGamePathLength);
- ImGui.InputTextWithHint("##resolveInversePath", "Reverse-resolve this path...", ref _currentReversePath,
- Utf8GamePath.MaxGamePathLength);
- ImGui.InputInt("##resolveIdx", ref _currentReverseIdx, 0, 0);
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(ResolveDefaultPath.Label, "Default Collection Resolve");
- if (_currentResolvePath.Length != 0)
- ImGui.TextUnformatted(new ResolveDefaultPath(pi).Invoke(_currentResolvePath));
-
- IpcTester.DrawIntro(ResolveInterfacePath.Label, "Interface Collection Resolve");
- if (_currentResolvePath.Length != 0)
- ImGui.TextUnformatted(new ResolveInterfacePath(pi).Invoke(_currentResolvePath));
-
- IpcTester.DrawIntro(ResolvePlayerPath.Label, "Player Collection Resolve");
- if (_currentResolvePath.Length != 0)
- ImGui.TextUnformatted(new ResolvePlayerPath(pi).Invoke(_currentResolvePath));
-
- IpcTester.DrawIntro(ResolveGameObjectPath.Label, "Game Object Collection Resolve");
- if (_currentResolvePath.Length != 0)
- ImGui.TextUnformatted(new ResolveGameObjectPath(pi).Invoke(_currentResolvePath, _currentReverseIdx));
-
- IpcTester.DrawIntro(ReverseResolvePlayerPath.Label, "Reversed Game Paths (Player)");
- if (_currentReversePath.Length > 0)
- {
- var list = new ReverseResolvePlayerPath(pi).Invoke(_currentReversePath);
- if (list.Length > 0)
- {
- ImGui.TextUnformatted(list[0]);
- if (list.Length > 1 && ImGui.IsItemHovered())
- ImGui.SetTooltip(string.Join("\n", list.Skip(1)));
- }
- }
-
- IpcTester.DrawIntro(ReverseResolveGameObjectPath.Label, "Reversed Game Paths (Game Object)");
- if (_currentReversePath.Length > 0)
- {
- var list = new ReverseResolveGameObjectPath(pi).Invoke(_currentReversePath, _currentReverseIdx);
- if (list.Length > 0)
- {
- ImGui.TextUnformatted(list[0]);
- if (list.Length > 1 && ImGui.IsItemHovered())
- ImGui.SetTooltip(string.Join("\n", list.Skip(1)));
- }
- }
-
- var forwardArray = _currentResolvePath.Length > 0
- ? [_currentResolvePath]
- : Array.Empty();
- var reverseArray = _currentReversePath.Length > 0
- ? [_currentReversePath]
- : Array.Empty();
-
- IpcTester.DrawIntro(ResolvePlayerPaths.Label, "Resolved Paths (Player)");
- if (forwardArray.Length > 0 || reverseArray.Length > 0)
- {
- var ret = new ResolvePlayerPaths(pi).Invoke(forwardArray, reverseArray);
- ImGui.TextUnformatted(ConvertText(ret));
- }
-
- IpcTester.DrawIntro(ResolvePlayerPathsAsync.Label, "Resolved Paths Async (Player)");
- if (ImGui.Button("Start"))
- _task = new ResolvePlayerPathsAsync(pi).Invoke(forwardArray, reverseArray);
- var hovered = ImGui.IsItemHovered();
- ImGui.SameLine();
- ImGui.AlignTextToFramePadding();
- ImGui.TextUnformatted(_task.Status.ToString());
- if ((hovered || ImGui.IsItemHovered()) && _task.IsCompletedSuccessfully)
- ImGui.SetTooltip(ConvertText(_task.Result));
- return;
-
- static string ConvertText((string[], string[][]) data)
- {
- var text = string.Empty;
- if (data.Item1.Length > 0)
- {
- if (data.Item2.Length > 0)
- text = $"Forward: {data.Item1[0]} | Reverse: {string.Join("; ", data.Item2[0])}.";
- else
- text = $"Forward: {data.Item1[0]}.";
- }
- else if (data.Item2.Length > 0)
- {
- text = $"Reverse: {string.Join("; ", data.Item2[0])}.";
- }
-
- return text;
- }
- }
-}
diff --git a/Penumbra/Api/IpcTester/ResourceTreeIpcTester.cs b/Penumbra/Api/IpcTester/ResourceTreeIpcTester.cs
deleted file mode 100644
index e6c8d52e..00000000
--- a/Penumbra/Api/IpcTester/ResourceTreeIpcTester.cs
+++ /dev/null
@@ -1,350 +0,0 @@
-using Dalamud.Bindings.ImGui;
-using Dalamud.Game.ClientState.Objects.Enums;
-using Dalamud.Interface;
-using Dalamud.Interface.Utility;
-using Dalamud.Plugin;
-using OtterGui;
-using OtterGui.Extensions;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.GameData.Enums;
-using Penumbra.GameData.Interop;
-using Penumbra.GameData.Structs;
-
-namespace Penumbra.Api.IpcTester;
-
-public class ResourceTreeIpcTester(IDalamudPluginInterface pi, ObjectManager objects) : IUiService
-{
- private readonly Stopwatch _stopwatch = new();
-
- private string _gameObjectIndices = "0";
- private ResourceType _type = ResourceType.Mtrl;
- private bool _withUiData;
-
- private (string, Dictionary>?)[]? _lastGameObjectResourcePaths;
- private (string, Dictionary>?)[]? _lastPlayerResourcePaths;
- private (string, IReadOnlyDictionary?)[]? _lastGameObjectResourcesOfType;
- private (string, IReadOnlyDictionary?)[]? _lastPlayerResourcesOfType;
- private (string, ResourceTreeDto?)[]? _lastGameObjectResourceTrees;
- private (string, ResourceTreeDto)[]? _lastPlayerResourceTrees;
- private TimeSpan _lastCallDuration;
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Resource Tree");
- if (!_)
- return;
-
- ImGui.InputText("GameObject indices", ref _gameObjectIndices, 511);
- ImGuiUtil.GenericEnumCombo("Resource type", ImGui.CalcItemWidth(), _type, out _type, Enum.GetValues());
- ImGui.Checkbox("Also get names and icons", ref _withUiData);
-
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(GetGameObjectResourcePaths.Label, "Get GameObject resource paths");
- if (ImGui.Button("Get##GameObjectResourcePaths"))
- {
- var gameObjects = GetSelectedGameObjects();
- var subscriber = new GetGameObjectResourcePaths(pi);
- _stopwatch.Restart();
- var resourcePaths = subscriber.Invoke(gameObjects);
-
- _lastCallDuration = _stopwatch.Elapsed;
- _lastGameObjectResourcePaths = gameObjects
- .Select(i => GameObjectToString(i))
- .Zip(resourcePaths)
- .ToArray();
-
- ImGui.OpenPopup(nameof(GetGameObjectResourcePaths));
- }
-
- IpcTester.DrawIntro(GetPlayerResourcePaths.Label, "Get local player resource paths");
- if (ImGui.Button("Get##PlayerResourcePaths"))
- {
- var subscriber = new GetPlayerResourcePaths(pi);
- _stopwatch.Restart();
- var resourcePaths = subscriber.Invoke();
-
- _lastCallDuration = _stopwatch.Elapsed;
- _lastPlayerResourcePaths = resourcePaths
- .Select(pair => (GameObjectToString(pair.Key), pair.Value))
- .ToArray()!;
-
- ImGui.OpenPopup(nameof(GetPlayerResourcePaths));
- }
-
- IpcTester.DrawIntro(GetGameObjectResourcesOfType.Label, "Get GameObject resources of type");
- if (ImGui.Button("Get##GameObjectResourcesOfType"))
- {
- var gameObjects = GetSelectedGameObjects();
- var subscriber = new GetGameObjectResourcesOfType(pi);
- _stopwatch.Restart();
- var resourcesOfType = subscriber.Invoke(_type, _withUiData, gameObjects);
-
- _lastCallDuration = _stopwatch.Elapsed;
- _lastGameObjectResourcesOfType = gameObjects
- .Select(i => GameObjectToString(i))
- .Zip(resourcesOfType)
- .ToArray();
-
- ImGui.OpenPopup(nameof(GetGameObjectResourcesOfType));
- }
-
- IpcTester.DrawIntro(GetPlayerResourcesOfType.Label, "Get local player resources of type");
- if (ImGui.Button("Get##PlayerResourcesOfType"))
- {
- var subscriber = new GetPlayerResourcesOfType(pi);
- _stopwatch.Restart();
- var resourcesOfType = subscriber.Invoke(_type, _withUiData);
-
- _lastCallDuration = _stopwatch.Elapsed;
- _lastPlayerResourcesOfType = resourcesOfType
- .Select(pair => (GameObjectToString(pair.Key), (IReadOnlyDictionary?)pair.Value))
- .ToArray();
-
- ImGui.OpenPopup(nameof(GetPlayerResourcesOfType));
- }
-
- IpcTester.DrawIntro(GetGameObjectResourceTrees.Label, "Get GameObject resource trees");
- if (ImGui.Button("Get##GameObjectResourceTrees"))
- {
- var gameObjects = GetSelectedGameObjects();
- var subscriber = new GetGameObjectResourceTrees(pi);
- _stopwatch.Restart();
- var trees = subscriber.Invoke(_withUiData, gameObjects);
-
- _lastCallDuration = _stopwatch.Elapsed;
- _lastGameObjectResourceTrees = gameObjects
- .Select(i => GameObjectToString(i))
- .Zip(trees)
- .ToArray();
-
- ImGui.OpenPopup(nameof(GetGameObjectResourceTrees));
- }
-
- IpcTester.DrawIntro(GetPlayerResourceTrees.Label, "Get local player resource trees");
- if (ImGui.Button("Get##PlayerResourceTrees"))
- {
- var subscriber = new GetPlayerResourceTrees(pi);
- _stopwatch.Restart();
- var trees = subscriber.Invoke(_withUiData);
-
- _lastCallDuration = _stopwatch.Elapsed;
- _lastPlayerResourceTrees = trees
- .Select(pair => (GameObjectToString(pair.Key), pair.Value))
- .ToArray();
-
- ImGui.OpenPopup(nameof(GetPlayerResourceTrees));
- }
-
- DrawPopup(nameof(GetGameObjectResourcePaths), ref _lastGameObjectResourcePaths, DrawResourcePaths,
- _lastCallDuration);
- DrawPopup(nameof(GetPlayerResourcePaths), ref _lastPlayerResourcePaths!, DrawResourcePaths, _lastCallDuration);
-
- DrawPopup(nameof(GetGameObjectResourcesOfType), ref _lastGameObjectResourcesOfType, DrawResourcesOfType,
- _lastCallDuration);
- DrawPopup(nameof(GetPlayerResourcesOfType), ref _lastPlayerResourcesOfType, DrawResourcesOfType,
- _lastCallDuration);
-
- DrawPopup(nameof(GetGameObjectResourceTrees), ref _lastGameObjectResourceTrees, DrawResourceTrees,
- _lastCallDuration);
- DrawPopup(nameof(GetPlayerResourceTrees), ref _lastPlayerResourceTrees, DrawResourceTrees!, _lastCallDuration);
- }
-
- private static void DrawPopup(string popupId, ref T? result, Action drawResult, TimeSpan duration) where T : class
- {
- ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(1000, 500));
- using var popup = ImRaii.Popup(popupId);
- if (!popup)
- {
- result = null;
- return;
- }
-
- if (result == null)
- {
- ImGui.CloseCurrentPopup();
- return;
- }
-
- drawResult(result);
-
- ImGui.TextUnformatted($"Invoked in {duration.TotalMilliseconds} ms");
-
- if (ImGui.Button("Close", -Vector2.UnitX) || !ImGui.IsWindowFocused())
- {
- result = null;
- ImGui.CloseCurrentPopup();
- }
- }
-
- private static void DrawWithHeaders((string, T?)[] result, Action drawItem) where T : class
- {
- var firstSeen = new Dictionary();
- foreach (var (label, item) in result)
- {
- if (item == null)
- {
- ImRaii.TreeNode($"{label}: null", ImGuiTreeNodeFlags.Leaf).Dispose();
- continue;
- }
-
- if (firstSeen.TryGetValue(item, out var firstLabel))
- {
- ImRaii.TreeNode($"{label}: same as {firstLabel}", ImGuiTreeNodeFlags.Leaf).Dispose();
- continue;
- }
-
- firstSeen.Add(item, label);
-
- using var header = ImRaii.TreeNode(label);
- if (!header)
- continue;
-
- drawItem(item);
- }
- }
-
- private static void DrawResourcePaths((string, Dictionary>?)[] result)
- {
- DrawWithHeaders(result, paths =>
- {
- using var table = ImRaii.Table(string.Empty, 2, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- ImGui.TableSetupColumn("Actual Path", ImGuiTableColumnFlags.WidthStretch, 0.6f);
- ImGui.TableSetupColumn("Game Paths", ImGuiTableColumnFlags.WidthStretch, 0.4f);
- ImGui.TableHeadersRow();
-
- foreach (var (actualPath, gamePaths) in paths)
- {
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(actualPath);
- ImGui.TableNextColumn();
- foreach (var gamePath in gamePaths)
- ImGui.TextUnformatted(gamePath);
- }
- });
- }
-
- private void DrawResourcesOfType((string, IReadOnlyDictionary?)[] result)
- {
- DrawWithHeaders(result, resources =>
- {
- using var table = ImRaii.Table(string.Empty, _withUiData ? 3 : 2, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- ImGui.TableSetupColumn("Resource Handle", ImGuiTableColumnFlags.WidthStretch, 0.15f);
- ImGui.TableSetupColumn("Actual Path", ImGuiTableColumnFlags.WidthStretch, _withUiData ? 0.55f : 0.85f);
- if (_withUiData)
- ImGui.TableSetupColumn("Icon & Name", ImGuiTableColumnFlags.WidthStretch, 0.3f);
- ImGui.TableHeadersRow();
-
- foreach (var (resourceHandle, (actualPath, name, icon)) in resources)
- {
- ImGui.TableNextColumn();
- TextUnformattedMono($"0x{resourceHandle:X}");
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(actualPath);
- if (_withUiData)
- {
- ImGui.TableNextColumn();
- TextUnformattedMono(icon.ToString());
- ImGui.SameLine();
- ImGui.TextUnformatted(name);
- }
- }
- });
- }
-
- private void DrawResourceTrees((string, ResourceTreeDto?)[] result)
- {
- DrawWithHeaders(result, tree =>
- {
- ImGui.TextUnformatted($"Name: {tree.Name}\nRaceCode: {(GenderRace)tree.RaceCode}");
-
- using var table = ImRaii.Table(string.Empty, _withUiData ? 7 : 5, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Resizable);
- if (!table)
- return;
-
- if (_withUiData)
- {
- ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch, 0.5f);
- ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthStretch, 0.1f);
- ImGui.TableSetupColumn("Icon", ImGuiTableColumnFlags.WidthStretch, 0.15f);
- }
- else
- {
- ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthStretch, 0.5f);
- }
-
- ImGui.TableSetupColumn("Game Path", ImGuiTableColumnFlags.WidthStretch, 0.5f);
- ImGui.TableSetupColumn("Actual Path", ImGuiTableColumnFlags.WidthStretch, 0.5f);
- ImGui.TableSetupColumn("Object Address", ImGuiTableColumnFlags.WidthStretch, 0.2f);
- ImGui.TableSetupColumn("Resource Handle", ImGuiTableColumnFlags.WidthStretch, 0.2f);
- ImGui.TableHeadersRow();
-
- void DrawNode(ResourceNodeDto node)
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- var hasChildren = node.Children.Any();
- using var treeNode = ImRaii.TreeNode(
- $"{(_withUiData ? node.Name ?? "Unknown" : node.Type)}##{node.ObjectAddress:X8}",
- hasChildren
- ? ImGuiTreeNodeFlags.SpanFullWidth
- : ImGuiTreeNodeFlags.SpanFullWidth | ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.NoTreePushOnOpen);
- if (_withUiData)
- {
- ImGui.TableNextColumn();
- TextUnformattedMono(node.Type.ToString());
- ImGui.TableNextColumn();
- TextUnformattedMono(node.Icon.ToString());
- }
-
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(node.GamePath ?? "Unknown");
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(node.ActualPath);
- ImGui.TableNextColumn();
- TextUnformattedMono($"0x{node.ObjectAddress:X8}");
- ImGui.TableNextColumn();
- TextUnformattedMono($"0x{node.ResourceHandle:X8}");
-
- if (treeNode)
- foreach (var child in node.Children)
- DrawNode(child);
- }
-
- foreach (var node in tree.Nodes)
- DrawNode(node);
- });
- }
-
- private static void TextUnformattedMono(string text)
- {
- using var _ = ImRaii.PushFont(UiBuilder.MonoFont);
- ImGui.TextUnformatted(text);
- }
-
- private ushort[] GetSelectedGameObjects()
- => _gameObjectIndices.Split(',')
- .SelectWhere(index => (ushort.TryParse(index.Trim(), out var i), i))
- .ToArray();
-
- private unsafe string GameObjectToString(ObjectIndex gameObjectIndex)
- {
- var gameObject = objects[gameObjectIndex];
-
- return gameObject.Valid
- ? $"[{gameObjectIndex}] {gameObject.Utf8Name} ({(ObjectKind)gameObject.AsObject->ObjectKind})"
- : $"[{gameObjectIndex}] null";
- }
-}
diff --git a/Penumbra/Api/IpcTester/TemporaryIpcTester.cs b/Penumbra/Api/IpcTester/TemporaryIpcTester.cs
deleted file mode 100644
index d46c5728..00000000
--- a/Penumbra/Api/IpcTester/TemporaryIpcTester.cs
+++ /dev/null
@@ -1,319 +0,0 @@
-using Dalamud.Interface;
-using Dalamud.Plugin;
-using Dalamud.Bindings.ImGui;
-using OtterGui;
-using OtterGui.Extensions;
-using OtterGui.Raii;
-using OtterGui.Services;
-using OtterGui.Text;
-using Penumbra.Api.Api;
-using Penumbra.Api.Enums;
-using Penumbra.Api.IpcSubscribers;
-using Penumbra.Collections.Manager;
-using Penumbra.Mods;
-using Penumbra.Mods.Manager;
-using Penumbra.Services;
-
-namespace Penumbra.Api.IpcTester;
-
-public class TemporaryIpcTester(
- IDalamudPluginInterface pi,
- ModManager modManager,
- CollectionManager collections,
- TempModManager tempMods,
- TempCollectionManager tempCollections,
- SaveService saveService,
- Configuration config)
- : IUiService
-{
- public Guid LastCreatedCollectionId = Guid.Empty;
-
- private readonly bool _debug = Assembly.GetAssembly(typeof(TemporaryIpcTester))?.GetName().Version?.Major >= 9;
-
- private Guid? _tempGuid;
- private string _tempCollectionName = string.Empty;
- private string _tempCollectionGuidName = string.Empty;
- private string _tempModName = string.Empty;
- private string _modDirectory = string.Empty;
- private string _tempGamePath = "test/game/path.mtrl";
- private string _tempFilePath = "test/success.mtrl";
- private string _tempManipulation = string.Empty;
- private string _identity = string.Empty;
- private PenumbraApiEc _lastTempError;
- private int _tempActorIndex;
- private bool _forceOverwrite;
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("Temporary");
- if (!_)
- return;
-
- ImGui.InputTextWithHint("##identity", "Identity...", ref _identity, 128);
- ImGui.InputTextWithHint("##tempCollection", "Collection Name...", ref _tempCollectionName, 128);
- ImGuiUtil.GuidInput("##guid", "Collection GUID...", string.Empty, ref _tempGuid, ref _tempCollectionGuidName);
- ImGui.InputInt("##tempActorIndex", ref _tempActorIndex, 0, 0);
- ImGui.InputTextWithHint("##tempMod", "Temporary Mod Name...", ref _tempModName, 32);
- ImGui.InputTextWithHint("##mod", "Existing Mod Name...", ref _modDirectory, 256);
- ImGui.InputTextWithHint("##tempGame", "Game Path...", ref _tempGamePath, 256);
- ImGui.InputTextWithHint("##tempFile", "File Path...", ref _tempFilePath, 256);
- ImUtf8.InputText("##tempManip"u8, ref _tempManipulation, "Manipulation Base64 String..."u8);
- ImGui.Checkbox("Force Character Collection Overwrite", ref _forceOverwrite);
-
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro("Last Error", _lastTempError.ToString());
- ImGuiUtil.DrawTableColumn("Last Created Collection");
- ImGui.TableNextColumn();
- using (ImRaii.PushFont(UiBuilder.MonoFont))
- {
- ImGuiUtil.CopyOnClickSelectable(LastCreatedCollectionId.ToString());
- }
-
- IpcTester.DrawIntro(CreateTemporaryCollection.Label, "Create Temporary Collection");
- if (ImGui.Button("Create##Collection"))
- {
- _lastTempError = new CreateTemporaryCollection(pi).Invoke(_identity, _tempCollectionName, out LastCreatedCollectionId);
- if (_tempGuid == null)
- {
- _tempGuid = LastCreatedCollectionId;
- _tempCollectionGuidName = LastCreatedCollectionId.ToString();
- }
- }
-
- var guid = _tempGuid.GetValueOrDefault(Guid.Empty);
-
- IpcTester.DrawIntro(DeleteTemporaryCollection.Label, "Delete Temporary Collection");
- if (ImGui.Button("Delete##Collection"))
- _lastTempError = new DeleteTemporaryCollection(pi).Invoke(guid);
- ImGui.SameLine();
- if (ImGui.Button("Delete Last##Collection"))
- _lastTempError = new DeleteTemporaryCollection(pi).Invoke(LastCreatedCollectionId);
-
- IpcTester.DrawIntro(AssignTemporaryCollection.Label, "Assign Temporary Collection");
- if (ImGui.Button("Assign##NamedCollection"))
- _lastTempError = new AssignTemporaryCollection(pi).Invoke(guid, _tempActorIndex, _forceOverwrite);
-
- IpcTester.DrawIntro(AddTemporaryMod.Label, "Add Temporary Mod to specific Collection");
- if (ImGui.Button("Add##Mod"))
- _lastTempError = new AddTemporaryMod(pi).Invoke(_tempModName, guid,
- new Dictionary { { _tempGamePath, _tempFilePath } },
- _tempManipulation.Length > 0 ? _tempManipulation : string.Empty, int.MaxValue);
-
- IpcTester.DrawIntro(CreateTemporaryCollection.Label, "Copy Existing Collection");
- if (ImGuiUtil.DrawDisabledButton("Copy##Collection", Vector2.Zero,
- "Copies the effective list from the collection named in Temporary Mod Name...",
- !collections.Storage.ByName(_tempModName, out var copyCollection))
- && copyCollection is { HasCache: true })
- {
- var files = copyCollection.ResolvedFiles.ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value.Path.ToString());
- var manips = MetaApi.CompressMetaManipulations(copyCollection);
- _lastTempError = new AddTemporaryMod(pi).Invoke(_tempModName, guid, files, manips, 999);
- }
-
- IpcTester.DrawIntro(AddTemporaryModAll.Label, "Add Temporary Mod to all Collections");
- if (ImGui.Button("Add##All"))
- _lastTempError = new AddTemporaryModAll(pi).Invoke(_tempModName,
- new Dictionary { { _tempGamePath, _tempFilePath } },
- _tempManipulation.Length > 0 ? _tempManipulation : string.Empty, int.MaxValue);
-
- IpcTester.DrawIntro(RemoveTemporaryMod.Label, "Remove Temporary Mod from specific Collection");
- if (ImGui.Button("Remove##Mod"))
- _lastTempError = new RemoveTemporaryMod(pi).Invoke(_tempModName, guid, int.MaxValue);
-
- IpcTester.DrawIntro(RemoveTemporaryModAll.Label, "Remove Temporary Mod from all Collections");
- if (ImGui.Button("Remove##ModAll"))
- _lastTempError = new RemoveTemporaryModAll(pi).Invoke(_tempModName, int.MaxValue);
-
- IpcTester.DrawIntro(SetTemporaryModSettings.Label, "Set Temporary Mod Settings (to default) in specific Collection");
- if (ImUtf8.Button("Set##SetTemporary"u8))
- _lastTempError = new SetTemporaryModSettings(pi).Invoke(guid, _modDirectory, false, true, 1337,
- new Dictionary>(),
- "IPC Tester", 1337);
-
- IpcTester.DrawIntro(SetTemporaryModSettingsPlayer.Label, "Set Temporary Mod Settings (to default) in game object collection");
- if (ImUtf8.Button("Set##SetTemporaryPlayer"u8))
- _lastTempError = new SetTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, _modDirectory, false, true, 1337,
- new Dictionary>(),
- "IPC Tester", 1337);
-
- IpcTester.DrawIntro(RemoveTemporaryModSettings.Label, "Remove Temporary Mod Settings from specific Collection");
- if (ImUtf8.Button("Remove##RemoveTemporary"u8))
- _lastTempError = new RemoveTemporaryModSettings(pi).Invoke(guid, _modDirectory, 1337);
- ImGui.SameLine();
- if (ImUtf8.Button("Remove (Wrong Key)##RemoveTemporary"u8))
- _lastTempError = new RemoveTemporaryModSettings(pi).Invoke(guid, _modDirectory, 1338);
-
- IpcTester.DrawIntro(RemoveTemporaryModSettingsPlayer.Label, "Remove Temporary Mod Settings from game object Collection");
- if (ImUtf8.Button("Remove##RemoveTemporaryPlayer"u8))
- _lastTempError = new RemoveTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, _modDirectory, 1337);
- ImGui.SameLine();
- if (ImUtf8.Button("Remove (Wrong Key)##RemoveTemporaryPlayer"u8))
- _lastTempError = new RemoveTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, _modDirectory, 1338);
-
- IpcTester.DrawIntro(RemoveAllTemporaryModSettings.Label, "Remove All Temporary Mod Settings from specific Collection");
- if (ImUtf8.Button("Remove##RemoveAllTemporary"u8))
- _lastTempError = new RemoveAllTemporaryModSettings(pi).Invoke(guid, 1337);
- ImGui.SameLine();
- if (ImUtf8.Button("Remove (Wrong Key)##RemoveAllTemporary"u8))
- _lastTempError = new RemoveAllTemporaryModSettings(pi).Invoke(guid, 1338);
-
- IpcTester.DrawIntro(RemoveAllTemporaryModSettingsPlayer.Label, "Remove All Temporary Mod Settings from game object Collection");
- if (ImUtf8.Button("Remove##RemoveAllTemporaryPlayer"u8))
- _lastTempError = new RemoveAllTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, 1337);
- ImGui.SameLine();
- if (ImUtf8.Button("Remove (Wrong Key)##RemoveAllTemporaryPlayer"u8))
- _lastTempError = new RemoveAllTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, 1338);
-
- IpcTester.DrawIntro(QueryTemporaryModSettings.Label, "Query Temporary Mod Settings from specific Collection");
- ImUtf8.Button("Query##QueryTemporaryModSettings"u8);
- if (ImGui.IsItemHovered())
- {
- _lastTempError = new QueryTemporaryModSettings(pi).Invoke(guid, _modDirectory, out var settings, out var source, 1337);
- DrawTooltip(settings, source);
- }
-
- ImGui.SameLine();
- ImUtf8.Button("Query (Wrong Key)##RemoveAllTemporary"u8);
- if (ImGui.IsItemHovered())
- {
- _lastTempError = new QueryTemporaryModSettings(pi).Invoke(guid, _modDirectory, out var settings, out var source, 1338);
- DrawTooltip(settings, source);
- }
-
- IpcTester.DrawIntro(QueryTemporaryModSettingsPlayer.Label, "Query Temporary Mod Settings from game object Collection");
- ImUtf8.Button("Query##QueryTemporaryModSettingsPlayer"u8);
- if (ImGui.IsItemHovered())
- {
- _lastTempError =
- new QueryTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, _modDirectory, out var settings, out var source, 1337);
- DrawTooltip(settings, source);
- }
-
- ImGui.SameLine();
- ImUtf8.Button("Query (Wrong Key)##RemoveAllTemporaryPlayer"u8);
- if (ImGui.IsItemHovered())
- {
- _lastTempError =
- new QueryTemporaryModSettingsPlayer(pi).Invoke(_tempActorIndex, _modDirectory, out var settings, out var source, 1338);
- DrawTooltip(settings, source);
- }
-
- void DrawTooltip((bool ForceInherit, bool Enabled, int Priority, Dictionary> Settings)? settings, string source)
- {
- using var tt = ImUtf8.Tooltip();
- ImUtf8.Text($"Query returned {_lastTempError}");
- if (settings != null)
- ImUtf8.Text($"Settings created by {(source.Length == 0 ? "Unknown Source" : source)}:");
- else
- ImUtf8.Text(source.Length > 0 ? $"Locked by {source}." : "No settings exist.");
- ImGui.Separator();
- if (settings == null)
- {
-
- return;
- }
-
- using (ImUtf8.Group())
- {
- ImUtf8.Text("Force Inherit"u8);
- ImUtf8.Text("Enabled"u8);
- ImUtf8.Text("Priority"u8);
- foreach (var group in settings.Value.Settings.Keys)
- ImUtf8.Text(group);
- }
-
- ImGui.SameLine();
- using (ImUtf8.Group())
- {
- ImUtf8.Text($"{settings.Value.ForceInherit}");
- ImUtf8.Text($"{settings.Value.Enabled}");
- ImUtf8.Text($"{settings.Value.Priority}");
- foreach (var group in settings.Value.Settings.Values)
- ImUtf8.Text(string.Join("; ", group));
- }
- }
- }
-
- public void DrawCollections()
- {
- using var collTree = ImUtf8.TreeNode("Temporary Collections##TempCollections"u8);
- if (!collTree)
- return;
-
- using var table = ImUtf8.Table("##collTree"u8, 6, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- foreach (var (collection, idx) in tempCollections.Values.WithIndex())
- {
- using var id = ImRaii.PushId(idx);
- ImGui.TableNextColumn();
- var character = tempCollections.Collections.Where(p => p.Collection == collection).Select(p => p.DisplayName)
- .FirstOrDefault()
- ?? "Unknown";
- if (_debug && ImUtf8.Button("Save##Collection"u8))
- TemporaryMod.SaveTempCollection(config, saveService, modManager, collection, character);
-
- using (ImRaii.PushFont(UiBuilder.MonoFont))
- {
- ImGui.TableNextColumn();
- ImGuiUtil.CopyOnClickSelectable(collection.Identity.Identifier);
- }
-
- ImGuiUtil.DrawTableColumn(collection.Identity.Name);
- ImGuiUtil.DrawTableColumn(collection.ResolvedFiles.Count.ToString());
- ImGuiUtil.DrawTableColumn(collection.MetaCache?.Count.ToString() ?? "0");
- ImGuiUtil.DrawTableColumn(string.Join(", ",
- tempCollections.Collections.Where(p => p.Collection == collection).Select(c => c.DisplayName)));
- }
- }
-
- public void DrawMods()
- {
- using var modTree = ImRaii.TreeNode("Temporary Mods##TempMods");
- if (!modTree)
- return;
-
- using var table = ImRaii.Table("##modTree", 5, ImGuiTableFlags.SizingFixedFit);
-
- void PrintList(string collectionName, IReadOnlyList list)
- {
- foreach (var mod in list)
- {
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(mod.Name.Text);
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(mod.Priority.ToString());
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(collectionName);
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(mod.Default.Files.Count.ToString());
- if (ImGui.IsItemHovered())
- {
- using var tt = ImRaii.Tooltip();
- foreach (var (path, file) in mod.Default.Files)
- ImGui.TextUnformatted($"{path} -> {file}");
- }
-
- ImGui.TableNextColumn();
- ImGui.TextUnformatted(mod.TotalManipulations.ToString());
- if (ImGui.IsItemHovered())
- {
- using var tt = ImRaii.Tooltip();
- foreach (var identifier in mod.Default.Manipulations.Identifiers)
- ImGui.TextUnformatted(identifier.ToString());
- }
- }
- }
-
- if (table)
- {
- PrintList("All", tempMods.ModsForAllCollections);
- foreach (var (collection, list) in tempMods.Mods)
- PrintList(collection.Identity.Name, list);
- }
- }
-}
diff --git a/Penumbra/Api/IpcTester/UiIpcTester.cs b/Penumbra/Api/IpcTester/UiIpcTester.cs
deleted file mode 100644
index 852339c9..00000000
--- a/Penumbra/Api/IpcTester/UiIpcTester.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using Dalamud.Plugin;
-using Dalamud.Bindings.ImGui;
-using OtterGui.Raii;
-using OtterGui.Services;
-using Penumbra.Api.Enums;
-using Penumbra.Api.Helpers;
-using Penumbra.Api.IpcSubscribers;
-
-namespace Penumbra.Api.IpcTester;
-
-public class UiIpcTester : IUiService, IDisposable
-{
- private readonly IDalamudPluginInterface _pi;
- public readonly EventSubscriber PreSettingsTabBar;
- public readonly EventSubscriber PreSettingsPanel;
- public readonly EventSubscriber PostEnabled;
- public readonly EventSubscriber PostSettingsPanelDraw;
- public readonly EventSubscriber ChangedItemTooltip;
- public readonly EventSubscriber ChangedItemClicked;
-
- private string _lastDrawnMod = string.Empty;
- private DateTimeOffset _lastDrawnModTime = DateTimeOffset.MinValue;
- private bool _subscribedToTooltip;
- private bool _subscribedToClick;
- private string _lastClicked = string.Empty;
- private string _lastHovered = string.Empty;
- private TabType _selectTab = TabType.None;
- private string _modName = string.Empty;
- private PenumbraApiEc _ec = PenumbraApiEc.Success;
-
- public UiIpcTester(IDalamudPluginInterface pi)
- {
- _pi = pi;
- PreSettingsTabBar = IpcSubscribers.PreSettingsTabBarDraw.Subscriber(pi, UpdateLastDrawnMod);
- PreSettingsPanel = IpcSubscribers.PreSettingsDraw.Subscriber(pi, UpdateLastDrawnMod);
- PostEnabled = IpcSubscribers.PostEnabledDraw.Subscriber(pi, UpdateLastDrawnMod);
- PostSettingsPanelDraw = IpcSubscribers.PostSettingsDraw.Subscriber(pi, UpdateLastDrawnMod);
- ChangedItemTooltip = IpcSubscribers.ChangedItemTooltip.Subscriber(pi, AddedTooltip);
- ChangedItemClicked = IpcSubscribers.ChangedItemClicked.Subscriber(pi, AddedClick);
- PreSettingsTabBar.Disable();
- PreSettingsPanel.Disable();
- PostEnabled.Disable();
- PostSettingsPanelDraw.Disable();
- ChangedItemTooltip.Disable();
- ChangedItemClicked.Disable();
- }
-
- public void Dispose()
- {
- PreSettingsTabBar.Dispose();
- PreSettingsPanel.Dispose();
- PostEnabled.Dispose();
- PostSettingsPanelDraw.Dispose();
- ChangedItemTooltip.Dispose();
- ChangedItemClicked.Dispose();
- }
-
- public void Draw()
- {
- using var _ = ImRaii.TreeNode("UI");
- if (!_)
- return;
-
- using (var combo = ImRaii.Combo("Tab to Open at", _selectTab.ToString()))
- {
- if (combo)
- foreach (var val in Enum.GetValues())
- {
- if (ImGui.Selectable(val.ToString(), _selectTab == val))
- _selectTab = val;
- }
- }
-
- ImGui.InputTextWithHint("##openMod", "Mod to Open at...", ref _modName, 256);
- using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
-
- IpcTester.DrawIntro(IpcSubscribers.PostSettingsDraw.Label, "Last Drawn Mod");
- ImGui.TextUnformatted(_lastDrawnMod.Length > 0 ? $"{_lastDrawnMod} at {_lastDrawnModTime}" : "None");
-
- IpcTester.DrawIntro(IpcSubscribers.ChangedItemTooltip.Label, "Add Tooltip");
- if (ImGui.Checkbox("##tooltip", ref _subscribedToTooltip))
- {
- if (_subscribedToTooltip)
- ChangedItemTooltip.Enable();
- else
- ChangedItemTooltip.Disable();
- }
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastHovered);
-
- IpcTester.DrawIntro(IpcSubscribers.ChangedItemClicked.Label, "Subscribe Click");
- if (ImGui.Checkbox("##click", ref _subscribedToClick))
- {
- if (_subscribedToClick)
- ChangedItemClicked.Enable();
- else
- ChangedItemClicked.Disable();
- }
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_lastClicked);
- IpcTester.DrawIntro(OpenMainWindow.Label, "Open Mod Window");
- if (ImGui.Button("Open##window"))
- _ec = new OpenMainWindow(_pi).Invoke(_selectTab, _modName, _modName);
-
- ImGui.SameLine();
- ImGui.TextUnformatted(_ec.ToString());
-
- IpcTester.DrawIntro(CloseMainWindow.Label, "Close Mod Window");
- if (ImGui.Button("Close##window"))
- new CloseMainWindow(_pi).Invoke();
- }
-
- private void UpdateLastDrawnMod(string name)
- => (_lastDrawnMod, _lastDrawnModTime) = (name, DateTimeOffset.Now);
-
- private void UpdateLastDrawnMod(string name, float _1, float _2)
- => (_lastDrawnMod, _lastDrawnModTime) = (name, DateTimeOffset.Now);
-
- private void AddedTooltip(ChangedItemType type, uint id)
- {
- _lastHovered = $"{type} {id} at {DateTime.UtcNow.ToLocalTime().ToString(CultureInfo.CurrentCulture)}";
- ImGui.TextUnformatted("IPC Test Successful");
- }
-
- private void AddedClick(MouseButton button, ChangedItemType type, uint id)
- {
- _lastClicked = $"{button}-click on {type} {id} at {DateTime.UtcNow.ToLocalTime().ToString(CultureInfo.CurrentCulture)}";
- }
-}
diff --git a/Penumbra/Api/ModChangedItemAdapter.cs b/Penumbra/Api/ModChangedItemAdapter.cs
deleted file mode 100644
index 8d2d473c..00000000
--- a/Penumbra/Api/ModChangedItemAdapter.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using Penumbra.GameData.Data;
-using Penumbra.Mods.Manager;
-
-namespace Penumbra.Api;
-
-public sealed class ModChangedItemAdapter(WeakReference storage)
- : IReadOnlyDictionary>,
- IReadOnlyList<(string ModDirectory, IReadOnlyDictionary ChangedItems)>
-{
- IEnumerator<(string ModDirectory, IReadOnlyDictionary ChangedItems)>
- IEnumerable<(string ModDirectory, IReadOnlyDictionary ChangedItems)>.GetEnumerator()
- => Storage.Select(m => (m.Identifier, (IReadOnlyDictionary)new ChangedItemDictionaryAdapter(m.ChangedItems)))
- .GetEnumerator();
-
- public IEnumerator>> GetEnumerator()
- => Storage.Select(m => new KeyValuePair>(m.Identifier,
- new ChangedItemDictionaryAdapter(m.ChangedItems)))
- .GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator()
- => GetEnumerator();
-
- public int Count
- => Storage.Count;
-
- public bool ContainsKey(string key)
- => Storage.TryGetMod(key, string.Empty, out _);
-
- public bool TryGetValue(string key, [NotNullWhen(true)] out IReadOnlyDictionary? value)
- {
- if (Storage.TryGetMod(key, string.Empty, out var mod))
- {
- value = new ChangedItemDictionaryAdapter(mod.ChangedItems);
- return true;
- }
-
- value = null;
- return false;
- }
-
- public IReadOnlyDictionary this[string key]
- => TryGetValue(key, out var v) ? v : throw new KeyNotFoundException();
-
- (string ModDirectory, IReadOnlyDictionary ChangedItems)
- IReadOnlyList<(string ModDirectory, IReadOnlyDictionary ChangedItems)>.this[int index]
- {
- get
- {
- var m = Storage[index];
- return (m.Identifier, new ChangedItemDictionaryAdapter(m.ChangedItems));
- }
- }
-
- public IEnumerable Keys
- => Storage.Select(m => m.Identifier);
-
- public IEnumerable> Values
- => Storage.Select(m => new ChangedItemDictionaryAdapter(m.ChangedItems));
-
- private ModStorage Storage
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
- get => storage.TryGetTarget(out var t)
- ? t
- : throw new ObjectDisposedException("The underlying mod storage of this IPC container was disposed.");
- }
-
- private sealed class ChangedItemDictionaryAdapter(SortedList data) : IReadOnlyDictionary
- {
- public IEnumerator> GetEnumerator()
- => data.Select(d => new KeyValuePair(d.Key, d.Value?.ToInternalObject())).GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator()
- => GetEnumerator();
-
- public int Count
- => data.Count;
-
- public bool ContainsKey(string key)
- => data.ContainsKey(key);
-
- public bool TryGetValue(string key, out object? value)
- {
- if (data.TryGetValue(key, out var v))
- {
- value = v?.ToInternalObject();
- return true;
- }
-
- value = null;
- return false;
- }
-
- public object? this[string key]
- => data[key]?.ToInternalObject();
-
- public IEnumerable Keys
- => data.Keys;
-
- public IEnumerable