├── .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 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
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 |
--------------------------------------------------------------------------------