├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .idea ├── .gitignore ├── UplayR1Unlocker.iml ├── UplayR1Unlocker2.iml ├── cmake.xml ├── codeStyles │ └── codeStyleConfig.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── build.ps1 ├── res ├── UplayR1Unlocker.jsonc ├── extra_build_config.gen.h ├── uplay_r1.dll └── uplay_r164.dll ├── src ├── legacy_linker_exports.h ├── main.cpp ├── pch.hpp ├── unlocker │ ├── unlocker.cpp │ └── unlocker.hpp └── uplay │ ├── uplay.cpp │ └── uplay.hpp └── vcpkg.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = crlf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | max_line_length = 120 10 | tab_width = 4 11 | ij_continuation_indent_size = 4 12 | ij_formatter_off_tag = @formatter:off 13 | ij_formatter_on_tag = @formatter:on 14 | ij_formatter_tags_enabled = false 15 | ij_smart_tabs = false 16 | ij_visual_guides = none 17 | ij_wrap_on_typing = false 18 | 19 | [.editorconfig] 20 | ij_editorconfig_align_group_field_declarations = false 21 | ij_editorconfig_space_after_colon = false 22 | ij_editorconfig_space_after_comma = true 23 | ij_editorconfig_space_before_colon = false 24 | ij_editorconfig_space_before_comma = false 25 | ij_editorconfig_spaces_around_assignment_operators = true 26 | 27 | [{*.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}] 28 | max_line_length = 100 29 | ij_c_add_brief_tag = false 30 | ij_c_add_getter_prefix = true 31 | ij_c_add_setter_prefix = true 32 | ij_c_align_dictionary_pair_values = false 33 | ij_c_align_group_field_declarations = false 34 | ij_c_align_init_list_in_columns = true 35 | ij_c_align_multiline_array_initializer_expression = true 36 | ij_c_align_multiline_assignment = true 37 | ij_c_align_multiline_binary_operation = true 38 | ij_c_align_multiline_chained_methods = false 39 | ij_c_align_multiline_for = true 40 | ij_c_align_multiline_ternary_operation = false 41 | ij_c_array_initializer_comma_on_next_line = false 42 | ij_c_array_initializer_new_line_after_left_brace = false 43 | ij_c_array_initializer_right_brace_on_new_line = false 44 | ij_c_array_initializer_wrap = normal 45 | ij_c_assignment_wrap = off 46 | ij_c_binary_operation_sign_on_next_line = false 47 | ij_c_binary_operation_wrap = normal 48 | ij_c_blank_lines_after_class_header = 0 49 | ij_c_blank_lines_after_imports = 1 50 | ij_c_blank_lines_around_class = 1 51 | ij_c_blank_lines_around_field = 0 52 | ij_c_blank_lines_around_field_in_interface = 0 53 | ij_c_blank_lines_around_method = 1 54 | ij_c_blank_lines_around_method_in_interface = 1 55 | ij_c_blank_lines_around_namespace = 0 56 | ij_c_blank_lines_around_properties_in_declaration = 0 57 | ij_c_blank_lines_around_properties_in_interface = 0 58 | ij_c_blank_lines_before_imports = 1 59 | ij_c_blank_lines_before_method_body = 0 60 | ij_c_block_brace_placement = end_of_line 61 | ij_c_block_brace_style = end_of_line 62 | ij_c_block_comment_at_first_column = true 63 | ij_c_catch_on_new_line = false 64 | ij_c_class_brace_style = end_of_line 65 | ij_c_class_constructor_init_list_align_multiline = true 66 | ij_c_class_constructor_init_list_comma_on_next_line = false 67 | ij_c_class_constructor_init_list_new_line_after_colon = never 68 | ij_c_class_constructor_init_list_new_line_before_colon = if_long 69 | ij_c_class_constructor_init_list_wrap = normal 70 | ij_c_copy_is_deep = false 71 | ij_c_create_interface_for_categories = true 72 | ij_c_declare_generated_methods = true 73 | ij_c_description_include_member_names = true 74 | ij_c_discharged_short_ternary_operator = false 75 | ij_c_do_not_add_breaks = false 76 | ij_c_do_while_brace_force = never 77 | ij_c_else_on_new_line = false 78 | ij_c_enum_constants_comma_on_next_line = false 79 | ij_c_enum_constants_wrap = on_every_item 80 | ij_c_for_brace_force = never 81 | ij_c_for_statement_new_line_after_left_paren = false 82 | ij_c_for_statement_right_paren_on_new_line = false 83 | ij_c_for_statement_wrap = off 84 | ij_c_function_brace_placement = end_of_line 85 | ij_c_function_call_arguments_align_multiline = false 86 | ij_c_function_call_arguments_align_multiline_pars = false 87 | ij_c_function_call_arguments_comma_on_next_line = false 88 | ij_c_function_call_arguments_new_line_after_lpar = false 89 | ij_c_function_call_arguments_new_line_before_rpar = false 90 | ij_c_function_call_arguments_wrap = normal 91 | ij_c_function_non_top_after_return_type_wrap = normal 92 | ij_c_function_parameters_align_multiline = true 93 | ij_c_function_parameters_align_multiline_pars = false 94 | ij_c_function_parameters_comma_on_next_line = false 95 | ij_c_function_parameters_new_line_after_lpar = true 96 | ij_c_function_parameters_new_line_before_rpar = true 97 | ij_c_function_parameters_wrap = normal 98 | ij_c_function_top_after_return_type_wrap = normal 99 | ij_c_generate_additional_eq_operators = true 100 | ij_c_generate_additional_rel_operators = true 101 | ij_c_generate_class_constructor = true 102 | ij_c_generate_comparison_operators_use_std_tie = false 103 | ij_c_generate_instance_variables_for_properties = ask 104 | ij_c_generate_operators_as_members = true 105 | ij_c_header_guard_style_pattern = ${PROJECT_NAME}_${FILE_NAME}_${EXT} 106 | ij_c_if_brace_force = never 107 | ij_c_in_line_short_ternary_operator = true 108 | ij_c_indent_block_comment = true 109 | ij_c_indent_c_struct_members = 4 110 | ij_c_indent_case_from_switch = true 111 | ij_c_indent_class_members = 4 112 | ij_c_indent_directive_as_code = false 113 | ij_c_indent_implementation_members = 0 114 | ij_c_indent_inside_code_block = 4 115 | ij_c_indent_interface_members = 0 116 | ij_c_indent_interface_members_except_ivars_block = false 117 | ij_c_indent_namespace_members = 4 118 | ij_c_indent_preprocessor_directive = 0 119 | ij_c_indent_visibility_keywords = 0 120 | ij_c_insert_override = true 121 | ij_c_insert_virtual_with_override = false 122 | ij_c_introduce_auto_vars = false 123 | ij_c_introduce_const_params = false 124 | ij_c_introduce_const_vars = false 125 | ij_c_introduce_generate_property = false 126 | ij_c_introduce_generate_synthesize = true 127 | ij_c_introduce_globals_to_header = true 128 | ij_c_introduce_prop_to_private_category = false 129 | ij_c_introduce_static_consts = true 130 | ij_c_introduce_use_ns_types = false 131 | ij_c_ivars_prefix = _ 132 | ij_c_keep_blank_lines_before_end = 2 133 | ij_c_keep_blank_lines_before_right_brace = 2 134 | ij_c_keep_blank_lines_in_code = 2 135 | ij_c_keep_blank_lines_in_declarations = 2 136 | ij_c_keep_case_expressions_in_one_line = false 137 | ij_c_keep_control_statement_in_one_line = true 138 | ij_c_keep_directive_at_first_column = true 139 | ij_c_keep_first_column_comment = true 140 | ij_c_keep_line_breaks = true 141 | ij_c_keep_nested_namespaces_in_one_line = false 142 | ij_c_keep_simple_blocks_in_one_line = true 143 | ij_c_keep_simple_methods_in_one_line = true 144 | ij_c_keep_structures_in_one_line = true 145 | ij_c_lambda_capture_list_align_multiline = false 146 | ij_c_lambda_capture_list_align_multiline_bracket = false 147 | ij_c_lambda_capture_list_comma_on_next_line = false 148 | ij_c_lambda_capture_list_new_line_after_lbracket = false 149 | ij_c_lambda_capture_list_new_line_before_rbracket = false 150 | ij_c_lambda_capture_list_wrap = off 151 | ij_c_line_comment_add_space = false 152 | ij_c_line_comment_at_first_column = true 153 | ij_c_method_brace_placement = end_of_line 154 | ij_c_method_call_arguments_align_by_colons = true 155 | ij_c_method_call_arguments_align_multiline = false 156 | ij_c_method_call_arguments_special_dictionary_pairs_treatment = true 157 | ij_c_method_call_arguments_wrap = off 158 | ij_c_method_call_chain_wrap = off 159 | ij_c_method_parameters_align_by_colons = true 160 | ij_c_method_parameters_align_multiline = false 161 | ij_c_method_parameters_wrap = off 162 | ij_c_namespace_brace_placement = end_of_line 163 | ij_c_parentheses_expression_new_line_after_left_paren = false 164 | ij_c_parentheses_expression_right_paren_on_new_line = false 165 | ij_c_place_assignment_sign_on_next_line = false 166 | ij_c_property_nonatomic = true 167 | ij_c_put_ivars_to_implementation = true 168 | ij_c_refactor_compatibility_aliases_and_classes = true 169 | ij_c_refactor_properties_and_ivars = true 170 | ij_c_release_style = ivar 171 | ij_c_retain_object_parameters_in_constructor = true 172 | ij_c_semicolon_after_method_signature = false 173 | ij_c_shift_operation_align_multiline = true 174 | ij_c_shift_operation_wrap = normal 175 | ij_c_show_non_virtual_functions = false 176 | ij_c_space_after_colon = true 177 | ij_c_space_after_colon_in_foreach = true 178 | ij_c_space_after_colon_in_selector = false 179 | ij_c_space_after_comma = true 180 | ij_c_space_after_cup_in_blocks = false 181 | ij_c_space_after_dictionary_literal_colon = true 182 | ij_c_space_after_for_semicolon = true 183 | ij_c_space_after_init_list_colon = true 184 | ij_c_space_after_method_parameter_type_parentheses = false 185 | ij_c_space_after_method_return_type_parentheses = false 186 | ij_c_space_after_pointer_in_declaration = true 187 | ij_c_space_after_quest = true 188 | ij_c_space_after_reference_in_declaration = true 189 | ij_c_space_after_reference_in_rvalue = false 190 | ij_c_space_after_structures_rbrace = true 191 | ij_c_space_after_superclass_colon = true 192 | ij_c_space_after_type_cast = true 193 | ij_c_space_after_visibility_sign_in_method_declaration = true 194 | ij_c_space_before_autorelease_pool_lbrace = true 195 | ij_c_space_before_catch_keyword = true 196 | ij_c_space_before_catch_left_brace = true 197 | ij_c_space_before_catch_parentheses = true 198 | ij_c_space_before_category_parentheses = true 199 | ij_c_space_before_chained_send_message = true 200 | ij_c_space_before_class_left_brace = true 201 | ij_c_space_before_colon = true 202 | ij_c_space_before_colon_in_foreach = false 203 | ij_c_space_before_comma = false 204 | ij_c_space_before_dictionary_literal_colon = false 205 | ij_c_space_before_do_left_brace = true 206 | ij_c_space_before_else_keyword = true 207 | ij_c_space_before_else_left_brace = true 208 | ij_c_space_before_for_left_brace = true 209 | ij_c_space_before_for_parentheses = true 210 | ij_c_space_before_for_semicolon = false 211 | ij_c_space_before_if_left_brace = true 212 | ij_c_space_before_if_parentheses = true 213 | ij_c_space_before_init_list = false 214 | ij_c_space_before_init_list_colon = true 215 | ij_c_space_before_method_call_parentheses = false 216 | ij_c_space_before_method_left_brace = true 217 | ij_c_space_before_method_parentheses = false 218 | ij_c_space_before_namespace_lbrace = true 219 | ij_c_space_before_pointer_in_declaration = false 220 | ij_c_space_before_property_attributes_parentheses = false 221 | ij_c_space_before_protocols_brackets = true 222 | ij_c_space_before_quest = true 223 | ij_c_space_before_reference_in_declaration = false 224 | ij_c_space_before_superclass_colon = true 225 | ij_c_space_before_switch_left_brace = true 226 | ij_c_space_before_switch_parentheses = true 227 | ij_c_space_before_template_call_lt = false 228 | ij_c_space_before_template_declaration_lt = false 229 | ij_c_space_before_try_left_brace = true 230 | ij_c_space_before_while_keyword = true 231 | ij_c_space_before_while_left_brace = true 232 | ij_c_space_before_while_parentheses = true 233 | ij_c_space_between_adjacent_brackets = false 234 | ij_c_space_between_operator_and_punctuator = false 235 | ij_c_space_within_empty_array_initializer_braces = false 236 | ij_c_spaces_around_additive_operators = true 237 | ij_c_spaces_around_assignment_operators = true 238 | ij_c_spaces_around_bitwise_operators = true 239 | ij_c_spaces_around_equality_operators = true 240 | ij_c_spaces_around_lambda_arrow = true 241 | ij_c_spaces_around_logical_operators = true 242 | ij_c_spaces_around_multiplicative_operators = true 243 | ij_c_spaces_around_pm_operators = false 244 | ij_c_spaces_around_relational_operators = true 245 | ij_c_spaces_around_shift_operators = true 246 | ij_c_spaces_around_unary_operator = false 247 | ij_c_spaces_within_array_initializer_braces = true 248 | ij_c_spaces_within_braces = true 249 | ij_c_spaces_within_brackets = false 250 | ij_c_spaces_within_cast_parentheses = false 251 | ij_c_spaces_within_catch_parentheses = false 252 | ij_c_spaces_within_category_parentheses = false 253 | ij_c_spaces_within_empty_braces = false 254 | ij_c_spaces_within_empty_function_call_parentheses = false 255 | ij_c_spaces_within_empty_function_declaration_parentheses = false 256 | ij_c_spaces_within_empty_lambda_capture_list_bracket = false 257 | ij_c_spaces_within_empty_template_call_ltgt = false 258 | ij_c_spaces_within_empty_template_declaration_ltgt = false 259 | ij_c_spaces_within_for_parentheses = false 260 | ij_c_spaces_within_function_call_parentheses = false 261 | ij_c_spaces_within_function_declaration_parentheses = false 262 | ij_c_spaces_within_if_parentheses = false 263 | ij_c_spaces_within_lambda_capture_list_bracket = false 264 | ij_c_spaces_within_method_parameter_type_parentheses = false 265 | ij_c_spaces_within_method_return_type_parentheses = false 266 | ij_c_spaces_within_parentheses = false 267 | ij_c_spaces_within_property_attributes_parentheses = false 268 | ij_c_spaces_within_protocols_brackets = false 269 | ij_c_spaces_within_send_message_brackets = false 270 | ij_c_spaces_within_switch_parentheses = false 271 | ij_c_spaces_within_template_call_ltgt = false 272 | ij_c_spaces_within_template_declaration_ltgt = false 273 | ij_c_spaces_within_template_double_gt = true 274 | ij_c_spaces_within_while_parentheses = false 275 | ij_c_special_else_if_treatment = true 276 | ij_c_superclass_list_after_colon = never 277 | ij_c_superclass_list_align_multiline = true 278 | ij_c_superclass_list_before_colon = if_long 279 | ij_c_superclass_list_comma_on_next_line = false 280 | ij_c_superclass_list_wrap = on_every_item 281 | ij_c_tag_prefix_of_block_comment = at 282 | ij_c_tag_prefix_of_line_comment = back_slash 283 | ij_c_template_call_arguments_align_multiline = false 284 | ij_c_template_call_arguments_align_multiline_pars = false 285 | ij_c_template_call_arguments_comma_on_next_line = false 286 | ij_c_template_call_arguments_new_line_after_lt = false 287 | ij_c_template_call_arguments_new_line_before_gt = false 288 | ij_c_template_call_arguments_wrap = off 289 | ij_c_template_declaration_function_body_indent = false 290 | ij_c_template_declaration_function_wrap = split_into_lines 291 | ij_c_template_declaration_struct_body_indent = false 292 | ij_c_template_declaration_struct_wrap = split_into_lines 293 | ij_c_template_parameters_align_multiline = false 294 | ij_c_template_parameters_align_multiline_pars = false 295 | ij_c_template_parameters_comma_on_next_line = false 296 | ij_c_template_parameters_new_line_after_lt = false 297 | ij_c_template_parameters_new_line_before_gt = false 298 | ij_c_template_parameters_wrap = off 299 | ij_c_ternary_operation_signs_on_next_line = true 300 | ij_c_ternary_operation_wrap = normal 301 | ij_c_type_qualifiers_placement = before 302 | ij_c_use_modern_casts = true 303 | ij_c_use_setters_in_constructor = true 304 | ij_c_while_brace_force = never 305 | ij_c_while_on_new_line = false 306 | ij_c_wrap_property_declaration = off 307 | 308 | [{*.cmake,CMakeLists.txt}] 309 | ij_cmake_align_multiline_parameters_in_calls = false 310 | ij_cmake_force_commands_case = 2 311 | ij_cmake_keep_blank_lines_in_code = 2 312 | ij_cmake_space_before_for_parentheses = true 313 | ij_cmake_space_before_if_parentheses = true 314 | ij_cmake_space_before_method_call_parentheses = false 315 | ij_cmake_space_before_method_parentheses = false 316 | ij_cmake_space_before_while_parentheses = true 317 | ij_cmake_spaces_within_for_parentheses = false 318 | ij_cmake_spaces_within_if_parentheses = false 319 | ij_cmake_spaces_within_method_call_parentheses = false 320 | ij_cmake_spaces_within_method_parentheses = false 321 | ij_cmake_spaces_within_while_parentheses = false 322 | 323 | [{*.har,*.json,*.jsonc}] 324 | indent_size = 2 325 | ij_json_keep_blank_lines_in_code = 1 326 | ij_json_keep_indents_on_empty_lines = false 327 | ij_json_keep_line_breaks = true 328 | ij_json_space_after_colon = true 329 | ij_json_space_after_comma = true 330 | ij_json_space_before_colon = true 331 | ij_json_space_before_comma = false 332 | ij_json_spaces_within_braces = false 333 | ij_json_spaces_within_brackets = false 334 | ij_json_wrap_long_lines = false 335 | 336 | [{*.apinotes,*.yaml,*.yml,.clang-format,.clang-tidy,_clang-format}] 337 | indent_size = 2 338 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | on: push 3 | 4 | jobs: 5 | ci: 6 | name: CI 7 | uses: acidicoala/KoalaBox/.github/workflows/build-and-package.yml@f65864c2ce1616c0af7210caf4d103ca4672fe91 8 | permissions: 9 | contents: write 10 | with: 11 | modules: >- 12 | ["UplayR1Unlocker"] 13 | 14 | zip_command: > 15 | zip -j $ZIP_NAME 16 | artifacts/*/*.dll 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vcpkg"] 2 | path = vcpkg 3 | url = https://github.com/microsoft/vcpkg.git 4 | [submodule "KoalaBox"] 5 | path = KoalaBox 6 | url = https://acidicoala@github.com/acidicoala/KoalaBox.git 7 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/UplayR1Unlocker.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/UplayR1Unlocker2.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/cmake.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.21) 2 | 3 | include(KoalaBox/KoalaBox.cmake) 4 | 5 | configure_globals(KoalaBox) 6 | 7 | project(UplayR1Unlocker VERSION 2.0.0) 8 | 9 | set_32_and_64(ORIGINAL_DLL uplay_r1_loader uplay_r1_loader64) 10 | set_32_and_64(STORE_DLL uplay_r1 uplay_r164) 11 | 12 | configure_version_resource("https://github.com/acidicoala/UplayR1Unlocker") 13 | 14 | configure_exports_generator() 15 | configure_linker_exports( 16 | false 17 | "${ORIGINAL_DLL}_o" 18 | "${RES_DIR}/${STORE_DLL}.dll" 19 | "${SRC_DIR}/uplay" 20 | "${SRC_DIR}/uplay/uplay.cpp" 21 | ) 22 | 23 | configure_build_config(extra_build_config) 24 | 25 | configure_library( 26 | SHARED 27 | 28 | ${SRC_DIR}/unlocker/unlocker.cpp 29 | ${SRC_DIR}/uplay/uplay.cpp 30 | ${SRC_DIR}/main.cpp 31 | 32 | ${KOALABOX_SRC_DIR}/koalabox/dll_monitor/dll_monitor.cpp 33 | ${KOALABOX_SRC_DIR}/koalabox/hook/hook.cpp 34 | ${KOALABOX_SRC_DIR}/koalabox/loader/loader.cpp 35 | ${KOALABOX_SRC_DIR}/koalabox/file_logger/file_logger.cpp 36 | ${KOALABOX_SRC_DIR}/koalabox/util/util.cpp 37 | ${KOALABOX_SRC_DIR}/koalabox/win_util/win_util.cpp 38 | 39 | ${LINKER_EXPORTS} 40 | ) 41 | 42 | configure_precompile_headers(${CMAKE_PROJECT_NAME} ${SRC_DIR}/pch.hpp) 43 | 44 | configure_output_name(${ORIGINAL_DLL}) 45 | 46 | configure_include_directories() 47 | 48 | configure_dependencies(${CMAKE_PROJECT_NAME} PolyHook_2 nlohmann_json spdlog) 49 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2022 by acidicoala 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose 4 | with or without fee is hereby granted. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 7 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 8 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 9 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 10 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 11 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 12 | THIS SOFTWARE. 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🐨 Uplay R1 Unlocker 🔓 2 | 3 | Legit DLC Unlocker for Ubisoft Connect (R1) 4 | 5 | ## [Official forum topic] 6 | 7 | For user-friendly description, consult the official forum thread. This document is meant for developers. 8 | 9 | [Official forum topic]: https://cs.rin.ru/forum/viewtopic.php?p=2337576#p2337576 10 | 11 | ## ⚙ Configuration 12 | 13 | UplayR1Unlocker does not require any manual configuration. By default, it uses most reasonable options and tries to unlock all DLCs that it can. However, there might be circumstances in which you need more custom-tailored behaviour. In this case you can use a configuration file [`UplayR1Unlocker.json`](./res/UplayR1Unlocker.jsonc) that you can find in this repository. To use it, simply place it alongside the unlocker DLL. It will be read upon each launch of a game. Configuration file itself is optional, but options within the file are not. In the absence of the config file, default value specified below will be used. 14 | 15 | The description of each available option is presented below: 16 | 17 | - `logging`: Enables or disables logging into a _UplayR1Unlocker.log_ file. Default: `false`. 18 | - `lang`: String that overrides game language if it is not set to `default`. Default: `default`. 19 | - `hook_loader`: Specifies which DLL to hook. When `true`, the unlocker hooks `uplay_r1_loader(64).dll`. When `false`, it hooks `uplay_r1(64).dll`. Default: `false`. 20 | - `blacklist`: A list of IDs to keep locked. Default: `[]` (empty list). 21 | 22 | ## 👋 Acknowledgements 23 | 24 | This project makes use of the following open source projects: 25 | 26 | - [JSON for Modern C++](https://github.com/nlohmann/json) 27 | - [PolyHook 2.0](https://github.com/stevemk14ebr/PolyHook_2_0) 28 | - [spdlog](https://github.com/gabime/spdlog) 29 | 30 | ## 📄 License 31 | 32 | This software is licensed under [Zero Clause BSD] license, terms of which are available in [LICENSE.txt] 33 | 34 | 35 | [Zero Clause BSD]: https://choosealicense.com/licenses/0bsd/ 36 | 37 | [LICENSE.txt]: ./LICENSE.txt 38 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | Set-Location (Get-Item $PSScriptRoot) 2 | 3 | . ./KoalaBox/build.ps1 @args 4 | 5 | Build-Project 6 | -------------------------------------------------------------------------------- /res/UplayR1Unlocker.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "logging": false, 3 | "lang": "default", 4 | "hook_loader": false, 5 | "blacklist": [ 6 | // DLC IDs go here 7 | 0, 8 | 1 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /res/extra_build_config.gen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ORIGINAL_DLL "${ORIGINAL_DLL}" 4 | #define STORE_DLL "${STORE_DLL}" 5 | -------------------------------------------------------------------------------- /res/uplay_r1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidicoala/UplayR1Unlocker/9e25dabb993e9bc6c45032c802bd2bf3edc7c5d3/res/uplay_r1.dll -------------------------------------------------------------------------------- /res/uplay_r164.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidicoala/UplayR1Unlocker/9e25dabb993e9bc6c45032c802bd2bf3edc7c5d3/res/uplay_r164.dll -------------------------------------------------------------------------------- /src/legacy_linker_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN64 4 | 5 | #pragma comment(linker, "/export:UPLAY_FRIENDS_DisableFriendMenuItem=uplay_r1_loader64_o.UPLAY_FRIENDS_DisableFriendMenuItem") 6 | #pragma comment(linker, "/export:UPLAY_FRIENDS_EnableFriendMenuItem=uplay_r1_loader64_o.UPLAY_FRIENDS_EnableFriendMenuItem") 7 | #pragma comment(linker, "/export:UPLAY_PARTY_DisablePartyMemberMenuItem=uplay_r1_loader64_o.UPLAY_PARTY_DisablePartyMemberMenuItem") 8 | #pragma comment(linker, "/export:UPLAY_PARTY_EnablePartyMemberMenuItem=uplay_r1_loader64_o.UPLAY_PARTY_EnablePartyMemberMenuItem") 9 | #pragma comment(linker, "/export:UPLAY_PARTY_SetGuest=uplay_r1_loader64_o.UPLAY_PARTY_SetGuest") 10 | 11 | #else 12 | 13 | #pragma comment(linker, "/export:UPLAY_FRIENDS_DisableFriendMenuItem=uplay_r1_loader_o.UPLAY_FRIENDS_DisableFriendMenuItem") 14 | #pragma comment(linker, "/export:UPLAY_FRIENDS_EnableFriendMenuItem=uplay_r1_loader_o.UPLAY_FRIENDS_EnableFriendMenuItem") 15 | #pragma comment(linker, "/export:UPLAY_PARTY_DisablePartyMemberMenuItem=uplay_r1_loader_o.UPLAY_PARTY_DisablePartyMemberMenuItem") 16 | #pragma comment(linker, "/export:UPLAY_PARTY_EnablePartyMemberMenuItem=uplay_r1_loader_o.UPLAY_PARTY_EnablePartyMemberMenuItem") 17 | #pragma comment(linker, "/export:UPLAY_PARTY_SetGuest=uplay_r1_loader_o.UPLAY_PARTY_SetGuest") 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "unlocker/unlocker.hpp" 2 | 3 | #include "legacy_linker_exports.h" 4 | 5 | // This header will be populated at build time 6 | #include 7 | 8 | EXTERN_C BOOL WINAPI DllMain(HMODULE module, DWORD reason, LPVOID) { 9 | if (reason == DLL_PROCESS_ATTACH) { 10 | unlocker::init(module); 11 | } else if (reason == DLL_PROCESS_DETACH) { 12 | unlocker::shutdown(); 13 | } 14 | 15 | return TRUE; 16 | } 17 | -------------------------------------------------------------------------------- /src/pch.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "koalabox/pch.hpp" 4 | 5 | #include "3rd_party/json.hpp" 6 | #include "3rd_party/polyhook2.hpp" 7 | 8 | #include "koalabox/config_parser/config_parser.hpp" 9 | #include "koalabox/dll_monitor/dll_monitor.hpp" 10 | #include "koalabox/hook/hook.hpp" 11 | #include "koalabox/loader/loader.hpp" 12 | #include "koalabox/file_logger/file_logger.hpp" 13 | #include "koalabox/util/util.hpp" 14 | #include "koalabox/win_util/win_util.hpp" 15 | -------------------------------------------------------------------------------- /src/unlocker/unlocker.cpp: -------------------------------------------------------------------------------- 1 | #include "unlocker.hpp" 2 | #include "uplay/uplay.hpp" 3 | 4 | #include "koalabox/config_parser/config_parser.hpp" 5 | #include "koalabox/loader/loader.hpp" 6 | #include "koalabox/util/util.hpp" 7 | #include "koalabox/win_util/win_util.hpp" 8 | 9 | #include 10 | 11 | #define DETOUR(MODULE, FUNC) \ 12 | hook::detour(MODULE, #FUNC, reinterpret_cast(FUNC)); 13 | 14 | namespace unlocker { 15 | Config config = {}; // NOLINT(cert-err58-cpp) 16 | 17 | HMODULE original_library = nullptr; 18 | 19 | bool is_hook_mode = false; 20 | 21 | void init(const HMODULE& self_module) { 22 | DisableThreadLibraryCalls(self_module); 23 | 24 | const auto self_directory = loader::get_module_dir(self_module); 25 | 26 | config = config_parser::parse(self_directory / PROJECT_NAME".jsonc", true); 27 | 28 | if (config.logging) { 29 | logger = file_logger::create(self_directory / PROJECT_NAME".log"); 30 | } 31 | 32 | logger->info("🐨 {} 🔓 v{}", PROJECT_NAME, PROJECT_VERSION); 33 | 34 | const auto module_path = win_util::get_module_file_name(self_module); 35 | 36 | is_hook_mode = hook::is_hook_mode(self_module, ORIGINAL_DLL); 37 | 38 | if (is_hook_mode) { 39 | logger->info("🪝 Detected hook mode"); 40 | 41 | dll_monitor::init( 42 | config.hook_loader ? ORIGINAL_DLL : STORE_DLL, 43 | [](const HMODULE& library) { 44 | hook::init(); 45 | 46 | original_library = library; 47 | 48 | DETOUR(library, UPLAY_USER_IsOwned) 49 | 50 | if (config.lang != "default") { 51 | DETOUR(library, UPLAY_INSTALLER_GetLanguageUtf8) 52 | } 53 | 54 | logger->info("Hooking complete"); 55 | 56 | dll_monitor::shutdown(); 57 | } 58 | ); 59 | } else { 60 | logger->info("🔀 Detected proxy mode"); 61 | 62 | original_library = loader::load_original_library(self_directory, ORIGINAL_DLL); 63 | } 64 | 65 | logger->info("🚀 Initialization complete"); 66 | } 67 | 68 | void shutdown() { 69 | if (not is_hook_mode) { 70 | win_util::free_library(original_library); 71 | } 72 | 73 | logger->info("💀 Shutdown complete"); 74 | } 75 | 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/unlocker/unlocker.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "koalabox/koalabox.hpp" 4 | 5 | namespace unlocker { 6 | using namespace koalabox; 7 | 8 | typedef uint32_t ProductID; 9 | 10 | struct Config { 11 | bool logging = false; 12 | String lang = "default"; 13 | bool hook_loader = false; 14 | Set blacklist; 15 | 16 | NLOHMANN_DEFINE_TYPE_INTRUSIVE(Config, logging, lang, hook_loader, blacklist) 17 | }; 18 | 19 | extern Config config; 20 | 21 | extern HMODULE original_library; 22 | 23 | extern bool is_hook_mode; 24 | 25 | void init(const HMODULE& loader_library); 26 | 27 | void shutdown(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/uplay/uplay.cpp: -------------------------------------------------------------------------------- 1 | #include "uplay.hpp" 2 | 3 | #define GET_ORIGINAL_FUNCTION(FUNC) \ 4 | static const auto FUNC##_o = hook::get_original_function( \ 5 | unlocker::is_hook_mode, unlocker::original_library, #FUNC, FUNC \ 6 | ); 7 | 8 | // Used as: cmp eax, 1 9 | // Therefore, we must return int rather than a bool 10 | DLL_EXPORT(uint32_t) UPLAY_USER_IsOwned(const int aUplayId) { 11 | GET_ORIGINAL_FUNCTION(UPLAY_USER_IsOwned) 12 | const auto result = UPLAY_USER_IsOwned_o(aUplayId); 13 | 14 | const auto isOwned = not config.blacklist.contains(aUplayId); 15 | 16 | logger->debug( 17 | "{} -> aUplayId: {},\tisOwned: {}\t(legitimately owned: {})", 18 | __func__, aUplayId, isOwned, static_cast(result) 19 | ); 20 | 21 | return static_cast(isOwned); // implicit type conversion 22 | } 23 | 24 | DLL_EXPORT(PCSTR) UPLAY_INSTALLER_GetLanguageUtf8() { 25 | logger->debug(__func__); 26 | 27 | if (config.lang == "default") { 28 | GET_ORIGINAL_FUNCTION(UPLAY_INSTALLER_GetLanguageUtf8) 29 | const auto result = UPLAY_INSTALLER_GetLanguageUtf8_o(); 30 | 31 | logger->info("🔤 {} -> responding with original lang: {}", __func__, result); 32 | return result; 33 | } else { 34 | logger->info("🔤 {} -> responding with configured lang: {}", __func__, config.lang); 35 | return config.lang.c_str(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/uplay/uplay.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "unlocker/unlocker.hpp" 4 | 5 | #define DLL_EXPORT(TYPE) extern "C" _declspec(dllexport) TYPE 6 | 7 | using namespace unlocker; 8 | 9 | DLL_EXPORT(uint32_t) UPLAY_USER_IsOwned(int aUplayId); 10 | 11 | DLL_EXPORT(PCSTR) UPLAY_INSTALLER_GetLanguageUtf8(); 12 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uplay-r2-unlocker", 3 | "version": "0.0.0", 4 | "license": "0BSD", 5 | "dependencies": [ 6 | "nlohmann-json", 7 | "polyhook2", 8 | "spdlog" 9 | ] 10 | } 11 | --------------------------------------------------------------------------------