[
  {
    "path": ".editorconfig",
    "content": "[*]\ncharset = utf-8\nend_of_line = crlf\nindent_size = 4\nindent_style = space\ninsert_final_newline = true\nmax_line_length = 120\ntab_width = 4\nij_continuation_indent_size = 8\nij_formatter_off_tag = @formatter:off\nij_formatter_on_tag = @formatter:on\nij_formatter_tags_enabled = false\nij_smart_tabs = false\nij_visual_guides = none\nij_wrap_on_typing = false\n\n[.editorconfig]\nij_editorconfig_align_group_field_declarations = false\nij_editorconfig_space_after_colon = false\nij_editorconfig_space_after_comma = true\nij_editorconfig_space_before_colon = false\nij_editorconfig_space_before_comma = false\nij_editorconfig_spaces_around_assignment_operators = true\n\n[{*.c,*.c++,*.cc,*.cp,*.cpp,*.cu,*.cuh,*.cxx,*.h,*.h++,*.hh,*.hp,*.hpp,*.hxx,*.i,*.icc,*.ii,*.inl,*.ino,*.ipp,*.m,*.mm,*.pch,*.tcc,*.tpp,version.gen.rc}]\nij_c_add_brief_tag = false\nij_c_add_getter_prefix = true\nij_c_add_setter_prefix = true\nij_c_align_dictionary_pair_values = false\nij_c_align_group_field_declarations = false\nij_c_align_init_list_in_columns = true\nij_c_align_multiline_array_initializer_expression = true\nij_c_align_multiline_assignment = true\nij_c_align_multiline_binary_operation = true\nij_c_align_multiline_chained_methods = false\nij_c_align_multiline_for = true\nij_c_align_multiline_ternary_operation = false\nij_c_array_initializer_comma_on_next_line = false\nij_c_array_initializer_new_line_after_left_brace = false\nij_c_array_initializer_right_brace_on_new_line = false\nij_c_array_initializer_wrap = normal\nij_c_assignment_wrap = off\nij_c_binary_operation_sign_on_next_line = false\nij_c_binary_operation_wrap = normal\nij_c_blank_lines_after_class_header = 0\nij_c_blank_lines_after_imports = 1\nij_c_blank_lines_around_class = 1\nij_c_blank_lines_around_field = 0\nij_c_blank_lines_around_field_in_interface = 0\nij_c_blank_lines_around_method = 1\nij_c_blank_lines_around_method_in_interface = 1\nij_c_blank_lines_around_namespace = 0\nij_c_blank_lines_around_properties_in_declaration = 0\nij_c_blank_lines_around_properties_in_interface = 0\nij_c_blank_lines_before_imports = 1\nij_c_blank_lines_before_method_body = 0\nij_c_block_brace_placement = end_of_line\nij_c_block_brace_style = end_of_line\nij_c_block_comment_at_first_column = true\nij_c_catch_on_new_line = false\nij_c_class_brace_style = end_of_line\nij_c_class_constructor_init_list_align_multiline = true\nij_c_class_constructor_init_list_comma_on_next_line = false\nij_c_class_constructor_init_list_new_line_after_colon = never\nij_c_class_constructor_init_list_new_line_before_colon = if_long\nij_c_class_constructor_init_list_wrap = normal\nij_c_copy_is_deep = false\nij_c_create_interface_for_categories = true\nij_c_declare_generated_methods = true\nij_c_description_include_member_names = true\nij_c_discharged_short_ternary_operator = false\nij_c_do_not_add_breaks = false\nij_c_do_while_brace_force = never\nij_c_else_on_new_line = false\nij_c_enum_constants_comma_on_next_line = false\nij_c_enum_constants_wrap = on_every_item\nij_c_for_brace_force = never\nij_c_for_statement_new_line_after_left_paren = false\nij_c_for_statement_right_paren_on_new_line = false\nij_c_for_statement_wrap = off\nij_c_function_brace_placement = end_of_line\nij_c_function_call_arguments_align_multiline = false\nij_c_function_call_arguments_align_multiline_pars = false\nij_c_function_call_arguments_comma_on_next_line = false\nij_c_function_call_arguments_new_line_after_lpar = false\nij_c_function_call_arguments_new_line_before_rpar = false\nij_c_function_call_arguments_wrap = normal\nij_c_function_non_top_after_return_type_wrap = normal\nij_c_function_parameters_align_multiline = true\nij_c_function_parameters_align_multiline_pars = false\nij_c_function_parameters_comma_on_next_line = false\nij_c_function_parameters_new_line_after_lpar = true\nij_c_function_parameters_new_line_before_rpar = true\nij_c_function_parameters_wrap = normal\nij_c_function_top_after_return_type_wrap = normal\nij_c_generate_additional_eq_operators = true\nij_c_generate_additional_rel_operators = true\nij_c_generate_class_constructor = true\nij_c_generate_comparison_operators_use_std_tie = false\nij_c_generate_instance_variables_for_properties = ask\nij_c_generate_operators_as_members = true\nij_c_header_guard_style_pattern = ${PROJECT_NAME}_${FILE_NAME}_${EXT}\nij_c_if_brace_force = never\nij_c_in_line_short_ternary_operator = true\nij_c_indent_block_comment = true\nij_c_indent_c_struct_members = 4\nij_c_indent_case_from_switch = true\nij_c_indent_class_members = 4\nij_c_indent_directive_as_code = false\nij_c_indent_implementation_members = 0\nij_c_indent_inside_code_block = 4\nij_c_indent_interface_members = 0\nij_c_indent_interface_members_except_ivars_block = false\nij_c_indent_namespace_members = 4\nij_c_indent_preprocessor_directive = 0\nij_c_indent_visibility_keywords = 0\nij_c_insert_override = true\nij_c_insert_virtual_with_override = false\nij_c_introduce_auto_vars = false\nij_c_introduce_const_params = false\nij_c_introduce_const_vars = false\nij_c_introduce_generate_property = false\nij_c_introduce_generate_synthesize = true\nij_c_introduce_globals_to_header = true\nij_c_introduce_prop_to_private_category = false\nij_c_introduce_static_consts = true\nij_c_introduce_use_ns_types = false\nij_c_ivars_prefix = _\nij_c_keep_blank_lines_before_end = 1\nij_c_keep_blank_lines_before_right_brace = 1\nij_c_keep_blank_lines_in_code = 1\nij_c_keep_blank_lines_in_declarations = 1\nij_c_keep_case_expressions_in_one_line = false\nij_c_keep_control_statement_in_one_line = true\nij_c_keep_directive_at_first_column = true\nij_c_keep_first_column_comment = true\nij_c_keep_line_breaks = true\nij_c_keep_nested_namespaces_in_one_line = false\nij_c_keep_simple_blocks_in_one_line = true\nij_c_keep_simple_methods_in_one_line = true\nij_c_keep_structures_in_one_line = true\nij_c_lambda_capture_list_align_multiline = false\nij_c_lambda_capture_list_align_multiline_bracket = false\nij_c_lambda_capture_list_comma_on_next_line = false\nij_c_lambda_capture_list_new_line_after_lbracket = false\nij_c_lambda_capture_list_new_line_before_rbracket = false\nij_c_lambda_capture_list_wrap = off\nij_c_line_comment_add_space = false\nij_c_line_comment_at_first_column = true\nij_c_method_brace_placement = end_of_line\nij_c_method_call_arguments_align_by_colons = true\nij_c_method_call_arguments_align_multiline = false\nij_c_method_call_arguments_special_dictionary_pairs_treatment = true\nij_c_method_call_arguments_wrap = off\nij_c_method_call_chain_wrap = off\nij_c_method_parameters_align_by_colons = true\nij_c_method_parameters_align_multiline = false\nij_c_method_parameters_wrap = off\nij_c_namespace_brace_placement = end_of_line\nij_c_parentheses_expression_new_line_after_left_paren = false\nij_c_parentheses_expression_right_paren_on_new_line = false\nij_c_place_assignment_sign_on_next_line = false\nij_c_property_nonatomic = true\nij_c_put_ivars_to_implementation = true\nij_c_refactor_compatibility_aliases_and_classes = true\nij_c_refactor_properties_and_ivars = true\nij_c_release_style = ivar\nij_c_retain_object_parameters_in_constructor = true\nij_c_semicolon_after_method_signature = false\nij_c_shift_operation_align_multiline = true\nij_c_shift_operation_wrap = normal\nij_c_show_non_virtual_functions = false\nij_c_space_after_colon = true\nij_c_space_after_colon_in_foreach = true\nij_c_space_after_colon_in_selector = false\nij_c_space_after_comma = true\nij_c_space_after_cup_in_blocks = false\nij_c_space_after_dictionary_literal_colon = true\nij_c_space_after_for_semicolon = true\nij_c_space_after_init_list_colon = true\nij_c_space_after_method_parameter_type_parentheses = false\nij_c_space_after_method_return_type_parentheses = false\nij_c_space_after_pointer_in_declaration = true\nij_c_space_after_quest = true\nij_c_space_after_reference_in_declaration = true\nij_c_space_after_reference_in_rvalue = false\nij_c_space_after_structures_rbrace = true\nij_c_space_after_superclass_colon = true\nij_c_space_after_type_cast = true\nij_c_space_after_visibility_sign_in_method_declaration = true\nij_c_space_before_autorelease_pool_lbrace = true\nij_c_space_before_catch_keyword = true\nij_c_space_before_catch_left_brace = true\nij_c_space_before_catch_parentheses = true\nij_c_space_before_category_parentheses = true\nij_c_space_before_chained_send_message = true\nij_c_space_before_class_left_brace = true\nij_c_space_before_colon = true\nij_c_space_before_colon_in_foreach = false\nij_c_space_before_comma = false\nij_c_space_before_dictionary_literal_colon = false\nij_c_space_before_do_left_brace = true\nij_c_space_before_else_keyword = true\nij_c_space_before_else_left_brace = true\nij_c_space_before_for_left_brace = true\nij_c_space_before_for_parentheses = true\nij_c_space_before_for_semicolon = false\nij_c_space_before_if_left_brace = true\nij_c_space_before_if_parentheses = true\nij_c_space_before_init_list = false\nij_c_space_before_init_list_colon = true\nij_c_space_before_method_call_parentheses = false\nij_c_space_before_method_left_brace = true\nij_c_space_before_method_parentheses = false\nij_c_space_before_namespace_lbrace = true\nij_c_space_before_pointer_in_declaration = false\nij_c_space_before_property_attributes_parentheses = false\nij_c_space_before_protocols_brackets = true\nij_c_space_before_quest = true\nij_c_space_before_reference_in_declaration = false\nij_c_space_before_superclass_colon = true\nij_c_space_before_switch_left_brace = true\nij_c_space_before_switch_parentheses = true\nij_c_space_before_template_call_lt = false\nij_c_space_before_template_declaration_lt = false\nij_c_space_before_try_left_brace = true\nij_c_space_before_while_keyword = true\nij_c_space_before_while_left_brace = true\nij_c_space_before_while_parentheses = true\nij_c_space_between_adjacent_brackets = false\nij_c_space_between_operator_and_punctuator = false\nij_c_space_within_empty_array_initializer_braces = false\nij_c_spaces_around_additive_operators = true\nij_c_spaces_around_assignment_operators = true\nij_c_spaces_around_bitwise_operators = true\nij_c_spaces_around_equality_operators = true\nij_c_spaces_around_lambda_arrow = true\nij_c_spaces_around_logical_operators = true\nij_c_spaces_around_multiplicative_operators = true\nij_c_spaces_around_pm_operators = false\nij_c_spaces_around_relational_operators = true\nij_c_spaces_around_shift_operators = true\nij_c_spaces_around_unary_operator = false\nij_c_spaces_within_array_initializer_braces = true\nij_c_spaces_within_braces = true\nij_c_spaces_within_brackets = false\nij_c_spaces_within_cast_parentheses = false\nij_c_spaces_within_catch_parentheses = false\nij_c_spaces_within_category_parentheses = false\nij_c_spaces_within_empty_braces = false\nij_c_spaces_within_empty_function_call_parentheses = false\nij_c_spaces_within_empty_function_declaration_parentheses = false\nij_c_spaces_within_empty_lambda_capture_list_bracket = false\nij_c_spaces_within_empty_template_call_ltgt = false\nij_c_spaces_within_empty_template_declaration_ltgt = false\nij_c_spaces_within_for_parentheses = false\nij_c_spaces_within_function_call_parentheses = false\nij_c_spaces_within_function_declaration_parentheses = false\nij_c_spaces_within_if_parentheses = false\nij_c_spaces_within_lambda_capture_list_bracket = false\nij_c_spaces_within_method_parameter_type_parentheses = false\nij_c_spaces_within_method_return_type_parentheses = false\nij_c_spaces_within_parentheses = false\nij_c_spaces_within_property_attributes_parentheses = false\nij_c_spaces_within_protocols_brackets = false\nij_c_spaces_within_send_message_brackets = false\nij_c_spaces_within_switch_parentheses = false\nij_c_spaces_within_template_call_ltgt = false\nij_c_spaces_within_template_declaration_ltgt = false\nij_c_spaces_within_template_double_gt = true\nij_c_spaces_within_while_parentheses = false\nij_c_special_else_if_treatment = true\nij_c_superclass_list_after_colon = never\nij_c_superclass_list_align_multiline = true\nij_c_superclass_list_before_colon = if_long\nij_c_superclass_list_comma_on_next_line = false\nij_c_superclass_list_wrap = on_every_item\nij_c_tag_prefix_of_block_comment = at\nij_c_tag_prefix_of_line_comment = back_slash\nij_c_template_call_arguments_align_multiline = false\nij_c_template_call_arguments_align_multiline_pars = false\nij_c_template_call_arguments_comma_on_next_line = false\nij_c_template_call_arguments_new_line_after_lt = false\nij_c_template_call_arguments_new_line_before_gt = false\nij_c_template_call_arguments_wrap = off\nij_c_template_declaration_function_body_indent = false\nij_c_template_declaration_function_wrap = split_into_lines\nij_c_template_declaration_struct_body_indent = false\nij_c_template_declaration_struct_wrap = split_into_lines\nij_c_template_parameters_align_multiline = false\nij_c_template_parameters_align_multiline_pars = false\nij_c_template_parameters_comma_on_next_line = false\nij_c_template_parameters_new_line_after_lt = false\nij_c_template_parameters_new_line_before_gt = false\nij_c_template_parameters_wrap = off\nij_c_ternary_operation_signs_on_next_line = true\nij_c_ternary_operation_wrap = normal\nij_c_type_qualifiers_placement = before\nij_c_use_modern_casts = true\nij_c_use_setters_in_constructor = true\nij_c_while_brace_force = never\nij_c_while_on_new_line = false\nij_c_wrap_property_declaration = off\n\n[{*.cmake,CMakeLists.txt}]\nij_continuation_indent_size = 4\nij_cmake_align_multiline_parameters_in_calls = false\nij_cmake_force_commands_case = 2\nij_cmake_keep_blank_lines_in_code = 2\nij_cmake_space_before_for_parentheses = true\nij_cmake_space_before_if_parentheses = true\nij_cmake_space_before_method_call_parentheses = false\nij_cmake_space_before_method_parentheses = false\nij_cmake_space_before_while_parentheses = true\nij_cmake_spaces_within_for_parentheses = false\nij_cmake_spaces_within_if_parentheses = false\nij_cmake_spaces_within_method_call_parentheses = false\nij_cmake_spaces_within_method_parentheses = false\nij_cmake_spaces_within_while_parentheses = false\n\n[{*.har,*.json,*.jsonc}]\nindent_size = 2\nij_json_keep_blank_lines_in_code = 1\nij_json_keep_indents_on_empty_lines = false\nij_json_keep_line_breaks = true\nij_json_space_after_colon = true\nij_json_space_after_comma = true\nij_json_space_before_colon = true\nij_json_space_before_comma = false\nij_json_spaces_within_braces = false\nij_json_spaces_within_brackets = false\nij_json_wrap_long_lines = false\n\n[{*.apinotes,*.yaml,*.yml,.clang-format,.clang-tidy,_clang-format}]\nindent_size = 2\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Continuous Integration\non: push\n\njobs:\n  ci:\n    name: CI\n    uses: acidicoala/KoalaBox/.github/workflows/build-and-package.yml@db2ee8fa2074b05f8d876f54e2a36486d0e69258\n    permissions:\n      contents: write\n    with:\n      modules: >-\n        [\"UplayR2Unlocker\"]\n\n      zip_command: >\n        zip -j $ZIP_NAME\n        artifacts/*/*.dll\n\n      config: Debug\n"
  },
  {
    "path": ".gitignore",
    "content": "/build\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"vcpkg\"]\n\tpath = vcpkg\n\turl = https://github.com/microsoft/vcpkg.git\n[submodule \"KoalaBox\"]\n\tpath = KoalaBox\n\turl = https://acidicoala@github.com/acidicoala/KoalaBox.git\n"
  },
  {
    "path": ".idea/.gitignore",
    "content": "# Default ignored files\n/shelf/\n/workspace.xml\n# Editor-based HTTP Client requests\n/httpRequests/\n/misc.xml"
  },
  {
    "path": ".idea/UplayR2Unlocker2.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module classpath=\"CMake\" type=\"CPP_MODULE\" version=\"4\" />"
  },
  {
    "path": ".idea/cmake.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CMakeSharedSettings\">\n    <configurations>\n      <configuration PROFILE_NAME=\"Debug [32]\" ENABLED=\"true\" GENERATION_DIR=\"build/32\" CONFIG_NAME=\"Debug\" TOOLCHAIN_NAME=\"Visual Studio 2022 [x86]\" GENERATION_OPTIONS=\"-G &quot;Visual Studio 17 2022&quot; -A Win32\">\n        <ADDITIONAL_GENERATION_ENVIRONMENT>\n          <envs>\n            <env name=\"VERSION_SUFFIX\" value=\"-debug\" />\n          </envs>\n        </ADDITIONAL_GENERATION_ENVIRONMENT>\n      </configuration>\n      <configuration PROFILE_NAME=\"Debug [64]\" ENABLED=\"true\" GENERATION_DIR=\"build/64\" CONFIG_NAME=\"Debug\" TOOLCHAIN_NAME=\"Visual Studio 2022 [amd64]\" GENERATION_OPTIONS=\"-G &quot;Visual Studio 17 2022&quot; -A x64\">\n        <ADDITIONAL_GENERATION_ENVIRONMENT>\n          <envs>\n            <env name=\"VERSION_SUFFIX\" value=\"-debug\" />\n          </envs>\n        </ADDITIONAL_GENERATION_ENVIRONMENT>\n      </configuration>\n      <configuration PROFILE_NAME=\"Release [64]\" ENABLED=\"false\" GENERATION_DIR=\"build/64\" CONFIG_NAME=\"Release\" TOOLCHAIN_NAME=\"Visual Studio 2022 [amd64]\" GENERATION_OPTIONS=\"-G &quot;Visual Studio 17 2022&quot; -A x64\" />\n    </configurations>\n  </component>\n</project>"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <option name=\"AUTODETECT_INDENTS\" value=\"false\" />\n    <option name=\"RIGHT_MARGIN\" value=\"100\" />\n    <option name=\"SOFT_MARGINS\" value=\"100\" />\n    <JSON>\n      <option name=\"OBJECT_WRAPPING\" value=\"1\" />\n      <option name=\"ARRAY_WRAPPING\" value=\"1\" />\n    </JSON>\n    <Objective-C>\n      <option name=\"KEEP_STRUCTURES_IN_ONE_LINE\" value=\"true\" />\n      <option name=\"FUNCTION_PARAMETERS_NEW_LINE_AFTER_LPAR\" value=\"true\" />\n      <option name=\"FUNCTION_PARAMETERS_NEW_LINE_BEFORE_RPAR\" value=\"true\" />\n      <option name=\"FUNCTION_CALL_ARGUMENTS_ALIGN_MULTILINE\" value=\"false\" />\n      <option name=\"SPACE_BEFORE_POINTER_IN_DECLARATION\" value=\"false\" />\n      <option name=\"SPACE_AFTER_POINTER_IN_DECLARATION\" value=\"true\" />\n      <option name=\"SPACE_BEFORE_REFERENCE_IN_DECLARATION\" value=\"false\" />\n      <option name=\"SPACE_AFTER_REFERENCE_IN_DECLARATION\" value=\"true\" />\n    </Objective-C>\n    <Objective-C-extensions>\n      <extensions>\n        <pair source=\"c\" header=\"h\" fileNamingConvention=\"PASCAL_CASE\" />\n        <pair source=\"cpp\" header=\"hpp\" fileNamingConvention=\"SNAKE_CASE\" />\n      </extensions>\n      <rules>\n        <rule entity=\"NAMESPACE\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"CAMEL_CASE\" suffix=\"\" />\n        <rule entity=\"MACRO\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"SCREAMING_SNAKE_CASE\" suffix=\"\" />\n        <rule entity=\"CLASS\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"PASCAL_CASE\" suffix=\"\" />\n        <rule entity=\"STRUCT\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"PASCAL_CASE\" suffix=\"\" />\n        <rule entity=\"ENUM\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"PASCAL_CASE\" suffix=\"\" />\n        <rule entity=\"ENUMERATOR\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"PASCAL_CASE\" suffix=\"\" />\n        <rule entity=\"TYPEDEF\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"NONE\" suffix=\"\" />\n        <rule entity=\"UNION\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"PASCAL_CASE\" suffix=\"\" />\n        <rule entity=\"CLASS_MEMBER_FUNCTION\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"CAMEL_CASE\" suffix=\"\" />\n        <rule entity=\"STRUCT_MEMBER_FUNCTION\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"CAMEL_CASE\" suffix=\"\" />\n        <rule entity=\"CLASS_MEMBER_FIELD\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"SNAKE_CASE\" suffix=\"\" />\n        <rule entity=\"STRUCT_MEMBER_FIELD\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"SNAKE_CASE\" suffix=\"\" />\n        <rule entity=\"GLOBAL_FUNCTION\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"CAMEL_CASE\" suffix=\"\" />\n        <rule entity=\"GLOBAL_VARIABLE\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"SCREAMING_SNAKE_CASE\" suffix=\"\" />\n        <rule entity=\"PARAMETER\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"SNAKE_CASE\" suffix=\"\" />\n        <rule entity=\"LOCAL_VARIABLE\" visibility=\"ANY\" specifier=\"ANY\" prefix=\"\" style=\"SNAKE_CASE\" suffix=\"\" />\n      </rules>\n    </Objective-C-extensions>\n    <codeStyleSettings language=\"CMake\">\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\n    </codeStyleSettings>\n    <codeStyleSettings language=\"JSON\">\n      <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n    </codeStyleSettings>\n    <codeStyleSettings language=\"Markdown\">\n      <option name=\"RIGHT_MARGIN\" value=\"999\" />\n      <indentOptions>\n        <option name=\"INDENT_SIZE\" value=\"2\" />\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n        <option name=\"TAB_SIZE\" value=\"2\" />\n      </indentOptions>\n    </codeStyleSettings>\n    <codeStyleSettings language=\"ObjectiveC\">\n      <option name=\"RIGHT_MARGIN\" value=\"100\" />\n      <option name=\"LINE_COMMENT_AT_FIRST_COLUMN\" value=\"false\" />\n      <option name=\"BLOCK_COMMENT_AT_FIRST_COLUMN\" value=\"false\" />\n      <option name=\"LINE_COMMENT_ADD_SPACE\" value=\"true\" />\n      <option name=\"KEEP_BLANK_LINES_IN_DECLARATIONS\" value=\"1\" />\n      <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n      <option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"1\" />\n      <option name=\"ALIGN_MULTILINE_TERNARY_OPERATION\" value=\"false\" />\n      <option name=\"SPACE_WITHIN_ARRAY_INITIALIZER_BRACES\" value=\"true\" />\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\n    </codeStyleSettings>\n    <codeStyleSettings language=\"PowerShell\">\n      <option name=\"BRACE_STYLE\" value=\"5\" />\n      <option name=\"CLASS_BRACE_STYLE\" value=\"5\" />\n      <option name=\"METHOD_BRACE_STYLE\" value=\"5\" />\n      <option name=\"ELSE_ON_NEW_LINE\" value=\"false\" />\n      <option name=\"SPECIAL_ELSE_IF_TREATMENT\" value=\"false\" />\n      <option name=\"KEEP_SIMPLE_BLOCKS_IN_ONE_LINE\" value=\"true\" />\n      <option name=\"KEEP_SIMPLE_METHODS_IN_ONE_LINE\" value=\"true\" />\n      <option name=\"KEEP_SIMPLE_CLASSES_IN_ONE_LINE\" value=\"true\" />\n    </codeStyleSettings>\n  </code_scheme>\n</component>"
  },
  {
    "path": ".idea/codeStyles/codeStyleConfig.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <state>\n    <option name=\"USE_PER_PROJECT_SETTINGS\" value=\"true\" />\n  </state>\n</component>"
  },
  {
    "path": ".idea/inspectionProfiles/Project_Default.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project Default\" />\n    <inspection_tool class=\"OCUnusedIncludeDirective\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\" />\n    <inspection_tool class=\"OCUnusedMacro\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\" />\n  </profile>\n</component>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/UplayR2Unlocker.iml\" filepath=\"$PROJECT_DIR$/.idea/UplayR2Unlocker.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/UplayR2Unlocker2.iml\" filepath=\"$PROJECT_DIR$/.idea/UplayR2Unlocker2.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n    <mapping directory=\"$PROJECT_DIR$/KoalaBox\" vcs=\"Git\" />\n    <mapping directory=\"$PROJECT_DIR$/vcpkg\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.21)\n\ninclude(KoalaBox/KoalaBox.cmake)\n\nconfigure_globals(KoalaBox)\n\nproject(UplayR2Unlocker VERSION 3.0.1)\n\nset_32_and_64(ORIGINAL_DLL upc_r2_loader upc_r2_loader64)\nset_32_and_64(LEGACY_ORIGINAL_DLL uplay_r2_loader uplay_r2_loader64)\n\nset_32_and_64(STORE_DLL uplay_r2 uplay_r264)\n\nconfigure_version_resource(\"https://github.com/acidicoala/UplayR2Unlocker\")\n\nset_32_and_64(DLL_INPUT \"${RES_DIR}/uplay_r2.dll\" \"${RES_DIR}/upc_r2_loader64.dll\")\nconfigure_exports_generator()\nconfigure_linker_exports(\n    false\n    \"${ORIGINAL_DLL}_o\"\n    ${DLL_INPUT}\n    \"${SRC_DIR}/upc\"\n    \"${SRC_DIR}/upc/upc.cpp\"\n)\n\nconfigure_build_config(extra_build_config)\n\nconfigure_library(\n    SHARED\n\n    ${SRC_DIR}/unlocker/unlocker.cpp\n    ${SRC_DIR}/upc/upc.cpp\n    ${SRC_DIR}/main.cpp\n\n    ${KOALABOX_SRC_DIR}/koalabox/dll_monitor/dll_monitor.cpp\n    ${KOALABOX_SRC_DIR}/koalabox/hook/hook.cpp\n    ${KOALABOX_SRC_DIR}/koalabox/loader/loader.cpp\n    ${KOALABOX_SRC_DIR}/koalabox/file_logger/file_logger.cpp\n    ${KOALABOX_SRC_DIR}/koalabox/util/util.cpp\n    ${KOALABOX_SRC_DIR}/koalabox/win_util/win_util.cpp\n\n    ${LINKER_EXPORTS}\n)\n\nconfigure_precompile_headers(${CMAKE_PROJECT_NAME} ${SRC_DIR}/pch.hpp)\n\nconfigure_output_name(${ORIGINAL_DLL})\n\nconfigure_include_directories()\n\nconfigure_dependencies(${CMAKE_PROJECT_NAME} cpr PolyHook_2 nlohmann_json spdlog)\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Copyright (C) 2022 by acidicoala\n\nPermission to use, copy, modify, and/or distribute this software for any purpose\nwith or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\nOF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\nTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\nTHIS SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "﻿# 🐨 Uplay R2 Unlocker 🔓\n\nLegit DLC Unlocker for Ubisoft Connect (R2)\n\n### [Official forum topic]\n\nFor user-friendly description, consult the official forum thread. This document is meant for developers.\n\n[Official forum topic]: https://cs.rin.ru/forum/viewtopic.php?f=10&t=111874\n\n### 👋 Acknowledgements\n\nCredit to Mr. Goldberg for the open source release of his Uplay R2 emulator.\n\nThis project makes use of the following open source projects:\n\n- [C++ Requests](https://github.com/libcpr/cpr)\n- [JSON for Modern C++](https://github.com/nlohmann/json)\n- [PolyHook 2.0](https://github.com/stevemk14ebr/PolyHook_2_0)\n- [spdlog](https://github.com/gabime/spdlog)\n\n### 📄 License\n\nThis software is licensed under [Zero Clause BSD] license, terms of which are available in [LICENSE.txt]\n\n[Zero Clause BSD]: https://choosealicense.com/licenses/0bsd/\n\n[LICENSE.txt]: ./LICENSE.txt\n"
  },
  {
    "path": "build.ps1",
    "content": "Set-Location (Get-Item $PSScriptRoot)\n\n. ./KoalaBox/build.ps1 @args\n\nBuild-Project\n"
  },
  {
    "path": "res/UplayR2Unlocker.jsonc",
    "content": "{\n  \"logging\": false,\n  \"lang\": \"default\",\n  \"auto_fetch\": true,\n  \"dlcs\": [],\n  \"items\": [],\n  \"blacklist\": []\n}\n"
  },
  {
    "path": "res/extra_build_config.gen.h",
    "content": "#pragma once\n\n#define ORIGINAL_DLL \"${ORIGINAL_DLL}\"\n#define LEGACY_ORIGINAL_DLL \"${LEGACY_ORIGINAL_DLL}\"\n\n#define STORE_DLL \"${STORE_DLL}\"\n"
  },
  {
    "path": "src/main.cpp",
    "content": "#include \"unlocker/unlocker.hpp\"\n\n// This header will be populated at build time\n#include <linker_exports.h>\n\nEXTERN_C BOOL WINAPI DllMain(HMODULE module, DWORD reason, LPVOID) {\n    if (reason == DLL_PROCESS_ATTACH) {\n        unlocker::init(module);\n    } else if (reason == DLL_PROCESS_DETACH) {\n        unlocker::shutdown();\n    }\n\n    return TRUE;\n}\n"
  },
  {
    "path": "src/pch.hpp",
    "content": "#pragma once\n\n#include \"koalabox/pch.hpp\"\n\n#include \"3rd_party/cpr.hpp\"\n#include \"3rd_party/json.hpp\"\n#include \"3rd_party/polyhook2.hpp\"\n\n#include \"koalabox/config_parser/config_parser.hpp\"\n#include \"koalabox/dll_monitor/dll_monitor.hpp\"\n#include \"koalabox/hook/hook.hpp\"\n#include \"koalabox/loader/loader.hpp\"\n#include \"koalabox/file_logger/file_logger.hpp\"\n#include \"koalabox/util/util.hpp\"\n#include \"koalabox/win_util/win_util.hpp\"\n"
  },
  {
    "path": "src/unlocker/unlocker.cpp",
    "content": "#include \"unlocker.hpp\"\n#include \"upc/upc.hpp\"\n\n#include \"koalabox/config_parser/config_parser.hpp\"\n#include \"koalabox/loader/loader.hpp\"\n#include \"koalabox/util/util.hpp\"\n#include \"koalabox/win_util/win_util.hpp\"\n\n#include <build_config.h>\n\n#define DETOUR(FUNC) \\\n    hook::detour(original_library, #FUNC, reinterpret_cast<FunctionPointer>(FUNC));\n\nnamespace unlocker {\n    Config config = {}; // NOLINT(cert-err58-cpp)\n\n    ProductID global_app_id = 0;\n\n    HMODULE original_library = nullptr;\n\n    bool is_hook_mode = false;\n\n    void init(const HMODULE& self_module) {\n        try {\n            DisableThreadLibraryCalls(self_module);\n\n            const auto self_directory = loader::get_module_dir(self_module);\n\n            config = config_parser::parse<Config>(self_directory / PROJECT_NAME\".jsonc\", true);\n\n            if (config.logging) {\n                logger = file_logger::create(self_directory / PROJECT_NAME\".log\");\n            }\n\n            logger->info(\"🐨 {} 🔓 v{}\", PROJECT_NAME, PROJECT_VERSION);\n\n            const auto module_path = win_util::get_module_file_name(self_module);\n\n            const auto is_not_original_dll = hook::is_hook_mode(self_module, ORIGINAL_DLL);\n            const auto is_not_legacy_dll = hook::is_hook_mode(self_module, LEGACY_ORIGINAL_DLL);\n\n            is_hook_mode = is_not_original_dll and is_not_legacy_dll;\n\n            if (is_hook_mode) {\n                logger->info(\"🪝 Detected hook mode\");\n\n                dll_monitor::init(STORE_DLL, [](const HMODULE& store_library) {\n                    hook::init();\n\n                    original_library = store_library;\n\n                    DETOUR(UPC_Init)\n                    DETOUR(UPC_InstallLanguageGet)\n                    DETOUR(UPC_ProductListFree)\n                    DETOUR(UPC_ProductListGet)\n\n                    logger->info(\"Hooking complete\");\n\n                    dll_monitor::shutdown();\n                });\n            } else {\n                logger->info(\"🔀 Detected proxy mode\");\n\n                original_library = loader::load_original_library(self_directory, ORIGINAL_DLL);\n            }\n\n            logger->info(\"🚀 Initialization complete\");\n        } catch (const Exception& ex) {\n            util::panic(fmt::format(\"Initialization error: {}\", ex.what()));\n        }\n    }\n\n    void shutdown() {\n        try {\n            if (not is_hook_mode) {\n                win_util::free_library(original_library);\n            }\n\n            logger->info(\"💀 Shutdown complete\");\n        } catch (const Exception& ex) {\n            logger->error(\"Shutdown error: {}\", ex.what());\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "src/unlocker/unlocker.hpp",
    "content": "#pragma once\n\n#include \"koalabox/koalabox.hpp\"\n\nnamespace unlocker {\n    using namespace koalabox;\n\n    typedef uint32_t ProductID;\n\n    struct Config {\n        bool logging = false;\n        String lang = \"default\";\n        bool auto_fetch = true;\n        Set<ProductID> dlcs;\n        Set<ProductID> items;\n        Set<ProductID> blacklist;\n\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE(Config, logging, lang, auto_fetch, dlcs, items, blacklist)\n    };\n\n    extern Config config;\n\n    extern HMODULE original_library;\n\n    extern ProductID global_app_id;\n\n    extern bool is_hook_mode;\n\n    void init(const HMODULE& loader_library);\n\n    void post_init();\n\n    void shutdown();\n\n}\n"
  },
  {
    "path": "src/upc/upc.cpp",
    "content": "#include \"upc.hpp\"\n\n#define GET_ORIGINAL_FUNCTION(FUNC) \\\n    static const auto FUNC##_o = hook::get_original_function( \\\n        unlocker::is_hook_mode, unlocker::original_library, #FUNC, FUNC \\\n    );\n\n\nString Product::get_type_string() const {\n    switch (type) {\n        case ProductType::App:\n            return \"App\";\n        case ProductType::DLC:\n            return \"DLC\";\n        case ProductType::Item:\n            return \"Item\";\n        default:\n            return \"Unexpected Type\";\n    }\n}\n\nvoid add_config_products(Map<ProductID, Product>& products) {\n    products.insert({ global_app_id, Product(global_app_id, ProductType::App) });\n\n    for (const auto& dlc_id: config.dlcs) {\n        products.insert({ dlc_id, Product(dlc_id, ProductType::DLC) });\n    }\n\n    for (const auto& item_id: config.items) {\n        products.insert({ item_id, Product(item_id, ProductType::Item) });\n    }\n}\n\nvoid add_fetched_products(Map<ProductID, Product>& products) {\n    if (not config.auto_fetch) {\n        return;\n    }\n\n    const auto res = cpr::Get(cpr::Url{\n        \"https://raw.githubusercontent.com/acidicoala/public-entitlements/main/ubisoft/v1/products.jsonc\"\n    });\n\n    if (res.status_code == cpr::status::HTTP_OK) {\n        try {\n            const auto json = nlohmann::json::parse(res.text, nullptr, true, true);\n\n            // iterate over keys to find the one that matches the game\n\n            for (const auto&[key, game]: json.items()) {\n                // Regex matching enables us to specify multiple IDs for the same game\n                if (std::regex_match(std::to_string(global_app_id), std::regex(key))) {\n                    const String name(game[\"name\"]);\n\n                    logger->info(\"Fetched products for game: '{}'\", name);\n\n                    for (const ProductID dlc: game[\"dlcs\"]) {\n                        logger->debug(\"  ID: {}, Type: DLC\", dlc);\n\n                        products.insert({ dlc, Product(dlc, ProductType::DLC) });\n                    }\n\n                    for (const ProductID item: game[\"items\"]) {\n                        logger->debug(\"  ID: {}, Type: Item\", item);\n\n                        products.insert({ item, Product(item, ProductType::Item) });\n                    }\n\n                    break;\n                }\n            }\n        } catch (const std::exception& ex) {\n            logger->error(\"Failed to parse fetched products: {}\", ex.what());\n        }\n    } else {\n        logger->error(\n            \"Failed to fetch product IDs. \"\n            \"Status code: {}. Text: {}\", res.status_code, res.text\n        );\n    }\n}\n\nvoid add_legit_products(Map<ProductID, Product>& products, const ProductList* legit_product_list) {\n    logger->info(\"Original product list contains {} elements:\", legit_product_list->length);\n\n    Vector<Product*> missing_products;\n\n    // Iterate over original product list to find missing items\n\n    for (uint32_t i = 0; i < legit_product_list->length; i++) {\n        const auto product = legit_product_list->data[i];\n\n        logger->debug(\n            \"  ID: {}, Type: {}, Mystery1: {}, Mystery2: {}, Always0: {}, Always3: {}\",\n            product->app_id, (int) product->type, product->mystery1,\n            product->mystery2, product->always_0, product->always_3\n        );\n\n        if (product->type == ProductType::App) {\n            continue;\n        }\n\n        // Insert missing products into the global product list\n        if (not products.contains(product->app_id)) {\n            products.insert({ product->app_id, Product(*product) });\n\n            missing_products.push_back(product);\n        }\n    }\n\n    // Let the user know which legitimately owned products are missing\n    if (not missing_products.empty()) {\n        logger->warn(\"Some of the legitimately owned products are missing from the config:\");\n\n        for (const auto missing_product: missing_products) {\n            logger->warn(\n                \"  ID: {}, Type: {}\",\n                missing_product->app_id,\n                missing_product->get_type_string()\n            );\n        }\n    }\n}\n\nVector<Product> get_filtered_products(Map<ProductID, Product>& products) {\n    Vector<Product> filtered_products;\n\n    // Construct a filtered list for game that excludes blacklisted ids\n\n    for (const auto&[id, product]: products) {\n        const auto included = not config.blacklist.contains(id);\n\n        if (included) {\n            filtered_products.push_back(product);\n        }\n\n        logger->debug(\n            \"  {} ID: {}, Type: {}\",\n            included ? \"✅\" : \"❌\", id, product.get_type_string()\n        );\n    }\n\n    return filtered_products;\n}\n\nProductList* create_new_product_list(const Vector<Product>& filtered_products) {\n    const auto product_list = new ProductList{\n        .length = static_cast<uint32_t>(filtered_products.size()),\n        .data = new Product* [filtered_products.size()]\n    };\n\n    for (size_t i = 0; i < filtered_products.size(); i++) {\n        product_list->data[i] = new Product(filtered_products.at(i));\n    }\n\n    return product_list;\n}\n\nDLL_EXPORT(int) UPC_Init(unsigned int version, ProductID app_id) {\n    logger->info(\"⚡ {} -> version: {}, app_id: {}\", __func__, version, app_id);\n\n    global_app_id = app_id;\n\n    GET_ORIGINAL_FUNCTION(UPC_Init)\n\n    const auto result = UPC_Init_o(version, app_id);\n\n    logger->debug(\"{} result: {}\", __func__, result);\n\n    return result;\n}\n\nDLL_EXPORT(int) UPC_ProductListFree(void*, ProductList* inProductList) {\n    logger->debug(__func__);\n\n    if (inProductList) {\n        for (uint32_t i = 0; i < inProductList->length; i++) {\n            delete inProductList->data[i];\n        }\n\n        delete[] inProductList->data;\n    }\n\n    delete inProductList;\n\n    return 0;\n}\n\nDLL_EXPORT(int) UPC_ProductListGet(\n    void* context,\n    const char* inOptUserIdUtf8,\n    unsigned int inFilter,\n    ProductList** outProductList,\n    UplayCallback inCallback,\n    void* inCallbackData\n) {\n    logger->debug(__func__);\n\n    const auto callbackContainer = new CallbackContainer{\n        .context = context,\n        .original_callback = inCallback,\n        .in_callback_data = inCallbackData,\n        .out_product_list = outProductList,\n    };\n\n    static const auto callback = [](unsigned long arg1, void* data) {\n        logger->debug(\"UPC_ProductListGet callback -> arg1: {}\", arg1);\n\n        const auto container = static_cast<CallbackContainer*>(data);\n\n        Map<ProductID, Product> products;\n\n        add_config_products(products);\n        add_fetched_products(products);\n        add_legit_products(products, container->legit_product_list);\n\n        logger->info(\"🍀 Unlocker prepared {} products:\", products.size());\n\n        const auto filtered_products = get_filtered_products(products);\n\n        const auto product_list = create_new_product_list(filtered_products);\n\n        // Save the product list address in the pointer provided by game earlier\n        *(container->out_product_list) = product_list;\n\n        // Let the game know that the product list is ready\n        container->original_callback(arg1, container->in_callback_data);\n\n        // Free the legit product list\n        GET_ORIGINAL_FUNCTION(UPC_ProductListFree)\n        UPC_ProductListFree_o(container->context, container->legit_product_list);\n\n        delete container;\n    };\n\n    GET_ORIGINAL_FUNCTION(UPC_ProductListGet)\n\n    return UPC_ProductListGet_o(\n        context,\n        inOptUserIdUtf8,\n        inFilter,\n        &callbackContainer->legit_product_list,\n        callback,\n        callbackContainer\n    );\n}\n\nDLL_EXPORT(const char*) UPC_InstallLanguageGet(void* context) {\n    logger->debug(__func__);\n\n    if (config.lang == \"default\") {\n        GET_ORIGINAL_FUNCTION(UPC_InstallLanguageGet)\n        const auto result = UPC_InstallLanguageGet_o(context);\n\n        logger->info(\"🔤 Responding with original language -> '{}'\", result);\n\n        return result;\n    } else {\n        logger->info(\"🔤 Responding with configured language -> '{}'\", config.lang);\n\n        return config.lang.c_str();\n    }\n}\n"
  },
  {
    "path": "src/upc/upc.hpp",
    "content": "#pragma once\n\n#include \"unlocker/unlocker.hpp\"\n\n#define DLL_EXPORT(TYPE) extern \"C\" _declspec(dllexport) TYPE\n\nusing namespace unlocker;\n\nenum class ProductType {\n    App = 1,\n    DLC = 2,\n    Item = 4,\n};\n\nstruct Product {\n    uint32_t app_id;\n\n    ProductType type;\n    [[maybe_unused]] uint32_t mystery1;\n    [[maybe_unused]] uint32_t always_3 = 3;\n    [[maybe_unused]] uint32_t always_0 = 0;\n    [[maybe_unused]] uint32_t mystery2;\n\n    Product(uint32_t app_id, ProductType type) {\n        this->app_id = app_id;\n        this->type = type;\n        this->mystery1 = type == ProductType::Item ? 4 : 1;\n        this->mystery2 = type == ProductType::Item ? 1 : 3;\n    }\n\n    [[nodiscard]]\n    String get_type_string() const;\n};\n\nstruct ProductList {\n    uint32_t length = 0;\n    [[maybe_unused]] uint32_t padding = 0; // What is this? offset?\n    Product** data = nullptr; // Array of pointers\n};\n\ntypedef void (* UplayCallback)(unsigned long, void*);\n\nstruct CallbackContainer {\n    void* context = nullptr;\n    UplayCallback original_callback = nullptr;\n    void* in_callback_data = nullptr;\n    ProductList* legit_product_list = nullptr;\n    ProductList** out_product_list = nullptr;\n};\n\nDLL_EXPORT(int) UPC_Init(unsigned int version, ProductID app_id);\n\nDLL_EXPORT(const char*) UPC_InstallLanguageGet(void* context);\n\nDLL_EXPORT(int) UPC_ProductListFree(void* context, ProductList* inProductList);\n\nDLL_EXPORT(int) UPC_ProductListGet(\n    void* context,\n    const char* inOptUserIdUtf8,\n    unsigned int inFilter,\n    ProductList** outProductList,\n    UplayCallback inCallback,\n    void* inCallbackData\n);"
  },
  {
    "path": "vcpkg.json",
    "content": "{\n  \"name\": \"uplay-r2-unlocker\",\n  \"version\": \"0.0.0\",\n  \"license\": \"0BSD\",\n  \"dependencies\": [\n    \"cpr\",\n    \"nlohmann-json\",\n    \"polyhook2\",\n    \"spdlog\"\n  ]\n}\n"
  }
]