@@ -6,6 +6,7 @@ import 'dart:typed_data';
6
6
import 'package:ffi/ffi.dart' ;
7
7
import 'package:reboot_common/common.dart' ;
8
8
import 'package:win32/win32.dart' ;
9
+ import 'package:path/path.dart' as path;
9
10
10
11
final DynamicLibrary _shell32 = DynamicLibrary .open ('shell32.dll' );
11
12
final SHGetPropertyStoreFromParsingName =
@@ -32,6 +33,122 @@ final Uint8List _patchedMatchmaking = Uint8List.fromList([
32
33
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
33
34
]);
34
35
36
+ // https://github.com/polynite/fn-releases
37
+ const Map <int , String > _buildToGameVersion = {
38
+ 2870186 : "1.0.0" ,
39
+ 3700114 : "1.7.2" ,
40
+ 3724489 : "1.8.0" ,
41
+ 3729133 : "1.8.1" ,
42
+ 3741772 : "1.8.2" ,
43
+ 3757339 : "1.9" ,
44
+ 3775276 : "1.9.1" ,
45
+ 3790078 : "1.10" ,
46
+ 3807424 : "1.11" ,
47
+ 3825894 : "2.1" ,
48
+ 3841827 : "2.2" ,
49
+ 3847564 : "2.3" ,
50
+ 3858292 : "2.4" ,
51
+ 3870737 : "2.4.2" ,
52
+ 3889387 : "2.5" ,
53
+ 3901517 : "3.0.0" ,
54
+ 3915963 : "3.1" ,
55
+ 3917250 : "3.1.1" ,
56
+ 3935073 : "3.2" ,
57
+ 3942182 : "3.3" ,
58
+ 4008490 : "3.5" ,
59
+ 4019403 : "3.6" ,
60
+ 4039451 : "4.0" ,
61
+ 4053532 : "4.1" ,
62
+ 4072250 : "4.2" ,
63
+ 4117433 : "4.4" ,
64
+ 4127312 : "4.4.1" ,
65
+ 4159770 : "4.5" ,
66
+ 4204761 : "5.0" ,
67
+ 4214610 : "5.01" ,
68
+ 4240749 : "5.10" ,
69
+ 4288479 : "5.21" ,
70
+ 4305896 : "5.30" ,
71
+ 4352937 : "5.40" ,
72
+ 4363240 : "5.41" ,
73
+ 4395664 : "6.0" ,
74
+ 4424678 : "6.01" ,
75
+ 4461277 : "6.0.2" ,
76
+ 4464155 : "6.10" ,
77
+ 4476098 : "6.10.1" ,
78
+ 4480234 : "6.10.2" ,
79
+ 4526925 : "6.21" ,
80
+ 4543176 : "6.22" ,
81
+ 4573279 : "6.31" ,
82
+ 4629139 : "7.0" ,
83
+ 4667333 : "7.10" ,
84
+ 4727874 : "7.20" ,
85
+ 4834550 : "7.30" ,
86
+ 5046157 : "7.40" ,
87
+ 5203069 : "8.00" ,
88
+ 5625478 : "8.20" ,
89
+ 5793395 : "8.30" ,
90
+ 6005771 : "8.40" ,
91
+ 6058028 : "8.50" ,
92
+ 6165369 : "8.51" ,
93
+ 6337466 : "9.00" ,
94
+ 6428087 : "9.01" ,
95
+ 6639283 : "9.10" ,
96
+ 6922310 : "9.21" ,
97
+ 7095426 : "9.30" ,
98
+ 7315705 : "9.40" ,
99
+ 7609292 : "9.41" ,
100
+ 7704164 : "10.00" ,
101
+ 7955722 : "10.10" ,
102
+ 8456527 : "10.20" ,
103
+ 8723043 : "10.31" ,
104
+ 9380822 : "10.40" ,
105
+ 9603448 : "11.00" ,
106
+ 9901083 : "11.10" ,
107
+ 10708866 : "11.30" ,
108
+ 10800459 : "11.31" ,
109
+ 11265652 : "11.50" ,
110
+ 11556442 : "12.00" ,
111
+ 11883027 : "12.10" ,
112
+ 12353830 : "12.21" ,
113
+ 12905909 : "12.41" ,
114
+ 13137020 : "12.50" ,
115
+ 13498980 : "12.61" ,
116
+ 14113327 : "13.40" ,
117
+ 14211474 : "14.00" ,
118
+ 14456520 : "14.30" ,
119
+ 14550713 : "14.40" ,
120
+ 14786821 : "14.60" ,
121
+ 14835335 : "15.00" ,
122
+ 15014719 : "15.10" ,
123
+ 15341163 : "15.30" ,
124
+ 15526472 : "15.50" ,
125
+ 15913292 : "16.10" ,
126
+ 16163563 : "16.30" ,
127
+ 16218553 : "16.40" ,
128
+ 16469788 : "16.50" ,
129
+ 16745144 : "17.10" ,
130
+ 17004569 : "17.30" ,
131
+ 17269705 : "17.40" ,
132
+ 17388565 : "17.50" ,
133
+ 17468642 : "18.00" ,
134
+ 17661844 : "18.10" ,
135
+ 17745267 : "18.20" ,
136
+ 17811397 : "18.21" ,
137
+ 17882303 : "18.30" ,
138
+ 18163738 : "18.40" ,
139
+ 18489740 : "19.01" ,
140
+ 18675304 : "19.10" ,
141
+ 19458861 : "20.00" ,
142
+ 19598943 : "20.10" ,
143
+ 19751212 : "20.20" ,
144
+ 19950687 : "20.30" ,
145
+ 20244966 : "20.40" ,
146
+ 20463113 : "21.00" ,
147
+ 20696680 : "21.10" ,
148
+ 21035704 : "21.20" ,
149
+ 21657658 : "21.50" ,
150
+ };
151
+
35
152
Future <bool > patchHeadless (File file) async =>
36
153
await _patch (file, _originalHeadless, _patchedHeadless);
37
154
@@ -179,8 +296,23 @@ String _parseUsername(String username, bool host) {
179
296
return username;
180
297
}
181
298
182
- Future <String > extractGameVersion (String filePath, String defaultGameVersion) => Isolate .run (() {
183
- final filePathPtr = filePath.toNativeUtf16 ();
299
+ // Parsing the version is not that easy
300
+ // Also on some versions the shipping exe has it as well, but not on all: that's why i'm using the crash report client
301
+ // ++Fortnite+Release-34.10-CL-40567068
302
+ // 4.16.0-3700114+++Fortnite+Release-Cert
303
+ // 4.19.0-3870737+++Fortnite+Release-Next
304
+ // 4.20.0-4008490+++Fortnite+Release-3.5
305
+ Future <String > extractGameVersion (Directory directory) => Isolate .run (() async {
306
+ log ("[VERSION] Looking for $kCrashReportExe in ${directory .path }" );
307
+ final defaultGameVersion = path.basename (directory.path);
308
+ final crashReportClients = await findFiles (directory, kCrashReportExe);
309
+ if (crashReportClients.isEmpty) {
310
+ log ("[VERSION] Didn't find a unique match: $crashReportClients " );
311
+ return defaultGameVersion;
312
+ }
313
+
314
+ log ("[VERSION] Extracting game version from ${crashReportClients .last .path }(default: $defaultGameVersion )" );
315
+ final filePathPtr = crashReportClients.last.path.toNativeUtf16 ();
184
316
final pPropertyStore = calloc <COMObject >();
185
317
final iidPropertyStore = GUIDFromString (IID_IPropertyStore );
186
318
final ret = SHGetPropertyStoreFromParsingName (
@@ -195,8 +327,9 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
195
327
calloc.free (iidPropertyStore);
196
328
197
329
if (FAILED (ret)) {
330
+ log ("[VERSION] Using default value" );
198
331
calloc.free (pPropertyStore);
199
- throw WindowsException (ret) ;
332
+ return defaultGameVersion ;
200
333
}
201
334
202
335
final propertyStore = IPropertyStore (pPropertyStore);
@@ -206,7 +339,8 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
206
339
final count = countPtr.value;
207
340
calloc.free (countPtr);
208
341
if (FAILED (hrCount)) {
209
- throw WindowsException (hrCount);
342
+ log ("[VERSION] Using default value" );
343
+ return defaultGameVersion;
210
344
}
211
345
212
346
for (var i = 0 ; i < count; i++ ) {
@@ -222,48 +356,20 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
222
356
if (! FAILED (hrValue)) {
223
357
if (pv.ref.vt == VARENUM .VT_LPWSTR ) {
224
358
final valueStr = pv.ref.pwszVal.toDartString ();
225
- if (valueStr.contains ("+++Fortnite" )) {
226
- var gameVersion = valueStr.substring (valueStr.lastIndexOf ("-" ) + 1 );
227
- if (gameVersion == "Cert" ) {
359
+ final headerIndex = valueStr.indexOf ("++Fortnite" );
360
+ if (headerIndex != - 1 ) {
361
+ log ("[VERSION] Found value string: $valueStr " );
362
+ var gameVersion = valueStr.substring (valueStr.indexOf ("-" , headerIndex) + 1 );
363
+ log ("[VERSION] Game version: $gameVersion " );
364
+ if (gameVersion == "Cert" || gameVersion == "Next" ) {
228
365
final engineVersion = valueStr.substring (0 , valueStr.indexOf ("+" ));
366
+ log ("[VERSION] Engine version: $engineVersion " );
229
367
final engineVersionParts = engineVersion.split ("-" );
230
368
final engineVersionBuild = int .parse (engineVersionParts[1 ]);
231
- switch (engineVersionBuild) {
232
- case 2870186 :
233
- gameVersion = "OT6.5" ;
234
- break ;
235
- case 3700114 :
236
- gameVersion = "1.7.2" ;
237
- break ;
238
- case 3724489 :
239
- gameVersion = "1.8.0" ;
240
- break ;
241
- case 3729133 :
242
- gameVersion = "1.8.1" ;
243
- break ;
244
- case 3741772 :
245
- gameVersion = "1.8.2" ;
246
- break ;
247
- case 3757339 :
248
- gameVersion = "1.9" ;
249
- break ;
250
- case 3775276 :
251
- gameVersion = "1.9.1" ;
252
- break ;
253
- case 3790078 :
254
- gameVersion = "1.10" ;
255
- break ;
256
- case 3807424 :
257
- gameVersion = "1.11" ;
258
- break ;
259
- case 3825894 :
260
- gameVersion = "2.1" ;
261
- break ;
262
- default :
263
- gameVersion = defaultGameVersion;
264
- break ;
265
- }
369
+ log ("[VERSION] Engine build: $engineVersionBuild " );
370
+ gameVersion = _buildToGameVersion[engineVersionBuild] ?? defaultGameVersion;
266
371
}
372
+ log ("[VERSION] Returning $gameVersion " );
267
373
return gameVersion;
268
374
}
269
375
}
@@ -272,5 +378,6 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
272
378
calloc.free (pv);
273
379
}
274
380
381
+ log ("[VERSION] Using default value" );
275
382
return defaultGameVersion;
276
383
});
0 commit comments