Skip to content

Commit 5d8f6bf

Browse files
committed
10.0.8
1 parent 9a000db commit 5d8f6bf

File tree

16 files changed

+205
-117
lines changed

16 files changed

+205
-117
lines changed

common/lib/common.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
export 'package:reboot_common/src/constant/backend.dart';
22
export 'package:reboot_common/src/constant/game.dart';
33
export 'package:reboot_common/src/constant/supabase.dart';
4-
export 'package:reboot_common/src/extension/process.dart';
54
export 'package:reboot_common/src/model/fortnite_build.dart';
65
export 'package:reboot_common/src/model/fortnite_version.dart';
76
export 'package:reboot_common/src/model/game_instance.dart';
@@ -15,4 +14,5 @@ export 'package:reboot_common/src/util/backend.dart';
1514
export 'package:reboot_common/src/util/downloader.dart';
1615
export 'package:reboot_common/src/util/os.dart';
1716
export 'package:reboot_common/src/util/log.dart';
18-
export 'package:reboot_common/src/util/game.dart';
17+
export 'package:reboot_common/src/util/game.dart';
18+
export 'package:reboot_common/src/util/extensions.dart';

common/lib/src/constant/game.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ const String kDisplayInitializedLine = "Initialized";
2929
const String kShippingExe = "FortniteClient-Win64-Shipping.exe";
3030
const String kLauncherExe = "FortniteLauncher.exe";
3131
const String kEacExe = "FortniteClient-Win64-Shipping_EAC.exe";
32+
const String kCrashReportExe = "CrashReportClient.exe";
3233
final Version kMaxAllowedVersion = Version.parse("30.10");

common/lib/src/extension/types.dart

Lines changed: 0 additions & 15 deletions
This file was deleted.

common/lib/src/util/backend.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'dart:io';
33

44
import 'package:ini/ini.dart';
55
import 'package:reboot_common/common.dart';
6-
import 'package:reboot_common/src/extension/types.dart';
6+
77
import 'package:shelf/shelf_io.dart';
88
import 'package:shelf_proxy/shelf_proxy.dart';
99
import 'package:sync/semaphore.dart';
@@ -234,7 +234,7 @@ Future<void> writeMatchmakingIp(String text) async {
234234
final splitIndex = text.indexOf(":");
235235
final ip = splitIndex != -1 ? text.substring(0, splitIndex) : text;
236236
var port = splitIndex != -1 ? text.substring(splitIndex + 1) : kDefaultGameServerPort;
237-
if(port.isBlank) {
237+
if(port.isBlankOrEmpty) {
238238
port = kDefaultGameServerPort;
239239
}
240240

common/lib/src/util/downloader.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'dart:async';
88
import 'dart:convert';
99
import 'dart:isolate';
1010

11-
import 'package:reboot_common/src/extension/types.dart';
1211
import 'package:uuid/uuid.dart';
1312

1413

@@ -361,7 +360,7 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
361360
);
362361
});
363362
process.stdError.listen((data) {
364-
if(!data.isBlank) {
363+
if(!data.isBlankOrEmpty) {
365364
_onError(data, options);
366365
}
367366
});
@@ -418,7 +417,7 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
418417
);
419418
});
420419
process.stdError.listen((data) {
421-
if(!data.isBlank) {
420+
if(!data.isBlankOrEmpty) {
422421
_onError(data, options);
423422
}
424423
});

common/lib/src/extension/process.dart renamed to common/lib/src/util/extensions.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,20 @@ extension ProcessExtension on Process {
55
Stream<String> get stdOutput => this.stdout.expand((event) => utf8.decode(event, allowMalformed: true).split("\n"));
66

77
Stream<String> get stdError => this.stderr.expand((event) => utf8.decode(event, allowMalformed: true).split("\n"));
8+
}
9+
10+
extension StringExtension on String {
11+
bool get isBlankOrEmpty {
12+
if(isEmpty) {
13+
return true;
14+
}
15+
16+
for(var char in this.split("")) {
17+
if(char != " ") {
18+
return false;
19+
}
20+
}
21+
22+
return true;
23+
}
824
}

common/lib/src/util/game.dart

Lines changed: 149 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:typed_data';
66
import 'package:ffi/ffi.dart';
77
import 'package:reboot_common/common.dart';
88
import 'package:win32/win32.dart';
9+
import 'package:path/path.dart' as path;
910

1011
final DynamicLibrary _shell32 = DynamicLibrary.open('shell32.dll');
1112
final SHGetPropertyStoreFromParsingName =
@@ -32,6 +33,122 @@ final Uint8List _patchedMatchmaking = Uint8List.fromList([
3233
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
3334
]);
3435

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+
35152
Future<bool> patchHeadless(File file) async =>
36153
await _patch(file, _originalHeadless, _patchedHeadless);
37154

@@ -179,8 +296,23 @@ String _parseUsername(String username, bool host) {
179296
return username;
180297
}
181298

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();
184316
final pPropertyStore = calloc<COMObject>();
185317
final iidPropertyStore = GUIDFromString(IID_IPropertyStore);
186318
final ret = SHGetPropertyStoreFromParsingName(
@@ -195,8 +327,9 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
195327
calloc.free(iidPropertyStore);
196328

197329
if (FAILED(ret)) {
330+
log("[VERSION] Using default value");
198331
calloc.free(pPropertyStore);
199-
throw WindowsException(ret);
332+
return defaultGameVersion;
200333
}
201334

202335
final propertyStore = IPropertyStore(pPropertyStore);
@@ -206,7 +339,8 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
206339
final count = countPtr.value;
207340
calloc.free(countPtr);
208341
if (FAILED(hrCount)) {
209-
throw WindowsException(hrCount);
342+
log("[VERSION] Using default value");
343+
return defaultGameVersion;
210344
}
211345

212346
for (var i = 0; i < count; i++) {
@@ -222,48 +356,20 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
222356
if (!FAILED(hrValue)) {
223357
if (pv.ref.vt == VARENUM.VT_LPWSTR) {
224358
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") {
228365
final engineVersion = valueStr.substring(0, valueStr.indexOf("+"));
366+
log("[VERSION] Engine version: $engineVersion");
229367
final engineVersionParts = engineVersion.split("-");
230368
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;
266371
}
372+
log("[VERSION] Returning $gameVersion");
267373
return gameVersion;
268374
}
269375
}
@@ -272,5 +378,6 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
272378
calloc.free(pv);
273379
}
274380

381+
log("[VERSION] Using default value");
275382
return defaultGameVersion;
276383
});

common/lib/src/util/log.dart

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import 'dart:io';
22

33
import 'package:reboot_common/common.dart';
4-
import 'package:sync/semaphore.dart';
4+
import 'package:synchronized/extension.dart';
55

66
final File launcherLogFile = _createLoggingFile();
7-
final Semaphore _semaphore = Semaphore(1);
87
bool enableLoggingToConsole = true;
98

109
File _createLoggingFile() {
@@ -19,14 +18,14 @@ File _createLoggingFile() {
1918

2019
void log(String message) async {
2120
try {
22-
await _semaphore.acquire();
2321
if(enableLoggingToConsole) {
2422
print(message);
2523
}
26-
await launcherLogFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
24+
25+
launcherLogFile.synchronized(() async {
26+
await launcherLogFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
27+
});
2728
}catch(error) {
2829
print("[LOGGER_ERROR] An error occurred while logging: $error");
29-
}finally {
30-
_semaphore.release();
3130
}
3231
}

common/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dependencies:
1919
uuid: ^4.5.1
2020
shelf_web_socket: ^2.0.0
2121
version: ^3.0.2
22+
synchronized: ^3.3.0+3
2223

2324
dev_dependencies:
2425
flutter_lints: ^5.0.0

0 commit comments

Comments
 (0)