mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 03:02:22 +01:00
10.0.8
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
export 'package:reboot_common/src/constant/backend.dart';
|
export 'package:reboot_common/src/constant/backend.dart';
|
||||||
export 'package:reboot_common/src/constant/game.dart';
|
export 'package:reboot_common/src/constant/game.dart';
|
||||||
export 'package:reboot_common/src/constant/supabase.dart';
|
export 'package:reboot_common/src/constant/supabase.dart';
|
||||||
export 'package:reboot_common/src/extension/process.dart';
|
|
||||||
export 'package:reboot_common/src/model/fortnite_build.dart';
|
export 'package:reboot_common/src/model/fortnite_build.dart';
|
||||||
export 'package:reboot_common/src/model/fortnite_version.dart';
|
export 'package:reboot_common/src/model/fortnite_version.dart';
|
||||||
export 'package:reboot_common/src/model/game_instance.dart';
|
export 'package:reboot_common/src/model/game_instance.dart';
|
||||||
@@ -16,3 +15,4 @@ export 'package:reboot_common/src/util/downloader.dart';
|
|||||||
export 'package:reboot_common/src/util/os.dart';
|
export 'package:reboot_common/src/util/os.dart';
|
||||||
export 'package:reboot_common/src/util/log.dart';
|
export 'package:reboot_common/src/util/log.dart';
|
||||||
export 'package:reboot_common/src/util/game.dart';
|
export 'package:reboot_common/src/util/game.dart';
|
||||||
|
export 'package:reboot_common/src/util/extensions.dart';
|
||||||
@@ -29,4 +29,5 @@ const String kDisplayInitializedLine = "Initialized";
|
|||||||
const String kShippingExe = "FortniteClient-Win64-Shipping.exe";
|
const String kShippingExe = "FortniteClient-Win64-Shipping.exe";
|
||||||
const String kLauncherExe = "FortniteLauncher.exe";
|
const String kLauncherExe = "FortniteLauncher.exe";
|
||||||
const String kEacExe = "FortniteClient-Win64-Shipping_EAC.exe";
|
const String kEacExe = "FortniteClient-Win64-Shipping_EAC.exe";
|
||||||
|
const String kCrashReportExe = "CrashReportClient.exe";
|
||||||
final Version kMaxAllowedVersion = Version.parse("30.10");
|
final Version kMaxAllowedVersion = Version.parse("30.10");
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
extension StringExtension on String {
|
|
||||||
bool get isBlank {
|
|
||||||
if(isEmpty) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var char in this.split("")) {
|
|
||||||
if(char != " ") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:ini/ini.dart';
|
import 'package:ini/ini.dart';
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_common/src/extension/types.dart';
|
|
||||||
import 'package:shelf/shelf_io.dart';
|
import 'package:shelf/shelf_io.dart';
|
||||||
import 'package:shelf_proxy/shelf_proxy.dart';
|
import 'package:shelf_proxy/shelf_proxy.dart';
|
||||||
import 'package:sync/semaphore.dart';
|
import 'package:sync/semaphore.dart';
|
||||||
@@ -234,7 +234,7 @@ Future<void> writeMatchmakingIp(String text) async {
|
|||||||
final splitIndex = text.indexOf(":");
|
final splitIndex = text.indexOf(":");
|
||||||
final ip = splitIndex != -1 ? text.substring(0, splitIndex) : text;
|
final ip = splitIndex != -1 ? text.substring(0, splitIndex) : text;
|
||||||
var port = splitIndex != -1 ? text.substring(splitIndex + 1) : kDefaultGameServerPort;
|
var port = splitIndex != -1 ? text.substring(splitIndex + 1) : kDefaultGameServerPort;
|
||||||
if(port.isBlank) {
|
if(port.isBlankOrEmpty) {
|
||||||
port = kDefaultGameServerPort;
|
port = kDefaultGameServerPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:reboot_common/src/extension/types.dart';
|
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
|
||||||
@@ -361,7 +360,7 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
process.stdError.listen((data) {
|
process.stdError.listen((data) {
|
||||||
if(!data.isBlank) {
|
if(!data.isBlankOrEmpty) {
|
||||||
_onError(data, options);
|
_onError(data, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -418,7 +417,7 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
process.stdError.listen((data) {
|
process.stdError.listen((data) {
|
||||||
if(!data.isBlank) {
|
if(!data.isBlankOrEmpty) {
|
||||||
_onError(data, options);
|
_onError(data, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,3 +6,19 @@ extension ProcessExtension on Process {
|
|||||||
|
|
||||||
Stream<String> get stdError => this.stderr.expand((event) => utf8.decode(event, allowMalformed: true).split("\n"));
|
Stream<String> get stdError => this.stderr.expand((event) => utf8.decode(event, allowMalformed: true).split("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension StringExtension on String {
|
||||||
|
bool get isBlankOrEmpty {
|
||||||
|
if(isEmpty) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var char in this.split("")) {
|
||||||
|
if(char != " ") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:win32/win32.dart';
|
import 'package:win32/win32.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
final DynamicLibrary _shell32 = DynamicLibrary.open('shell32.dll');
|
final DynamicLibrary _shell32 = DynamicLibrary.open('shell32.dll');
|
||||||
final SHGetPropertyStoreFromParsingName =
|
final SHGetPropertyStoreFromParsingName =
|
||||||
@@ -32,6 +33,122 @@ final Uint8List _patchedMatchmaking = Uint8List.fromList([
|
|||||||
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
|
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
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// https://github.com/polynite/fn-releases
|
||||||
|
const Map<int, String> _buildToGameVersion = {
|
||||||
|
2870186: "1.0.0",
|
||||||
|
3700114: "1.7.2",
|
||||||
|
3724489: "1.8.0",
|
||||||
|
3729133: "1.8.1",
|
||||||
|
3741772: "1.8.2",
|
||||||
|
3757339: "1.9",
|
||||||
|
3775276: "1.9.1",
|
||||||
|
3790078: "1.10",
|
||||||
|
3807424: "1.11",
|
||||||
|
3825894: "2.1",
|
||||||
|
3841827: "2.2",
|
||||||
|
3847564: "2.3",
|
||||||
|
3858292: "2.4",
|
||||||
|
3870737: "2.4.2",
|
||||||
|
3889387: "2.5",
|
||||||
|
3901517: "3.0.0",
|
||||||
|
3915963: "3.1",
|
||||||
|
3917250: "3.1.1",
|
||||||
|
3935073: "3.2",
|
||||||
|
3942182: "3.3",
|
||||||
|
4008490: "3.5",
|
||||||
|
4019403: "3.6",
|
||||||
|
4039451: "4.0",
|
||||||
|
4053532: "4.1",
|
||||||
|
4072250: "4.2",
|
||||||
|
4117433: "4.4",
|
||||||
|
4127312: "4.4.1",
|
||||||
|
4159770: "4.5",
|
||||||
|
4204761: "5.0",
|
||||||
|
4214610: "5.01",
|
||||||
|
4240749: "5.10",
|
||||||
|
4288479: "5.21",
|
||||||
|
4305896: "5.30",
|
||||||
|
4352937: "5.40",
|
||||||
|
4363240: "5.41",
|
||||||
|
4395664: "6.0",
|
||||||
|
4424678: "6.01",
|
||||||
|
4461277: "6.0.2",
|
||||||
|
4464155: "6.10",
|
||||||
|
4476098: "6.10.1",
|
||||||
|
4480234: "6.10.2",
|
||||||
|
4526925: "6.21",
|
||||||
|
4543176: "6.22",
|
||||||
|
4573279: "6.31",
|
||||||
|
4629139: "7.0",
|
||||||
|
4667333: "7.10",
|
||||||
|
4727874: "7.20",
|
||||||
|
4834550: "7.30",
|
||||||
|
5046157: "7.40",
|
||||||
|
5203069: "8.00",
|
||||||
|
5625478: "8.20",
|
||||||
|
5793395: "8.30",
|
||||||
|
6005771: "8.40",
|
||||||
|
6058028: "8.50",
|
||||||
|
6165369: "8.51",
|
||||||
|
6337466: "9.00",
|
||||||
|
6428087: "9.01",
|
||||||
|
6639283: "9.10",
|
||||||
|
6922310: "9.21",
|
||||||
|
7095426: "9.30",
|
||||||
|
7315705: "9.40",
|
||||||
|
7609292: "9.41",
|
||||||
|
7704164: "10.00",
|
||||||
|
7955722: "10.10",
|
||||||
|
8456527: "10.20",
|
||||||
|
8723043: "10.31",
|
||||||
|
9380822: "10.40",
|
||||||
|
9603448: "11.00",
|
||||||
|
9901083: "11.10",
|
||||||
|
10708866: "11.30",
|
||||||
|
10800459: "11.31",
|
||||||
|
11265652: "11.50",
|
||||||
|
11556442: "12.00",
|
||||||
|
11883027: "12.10",
|
||||||
|
12353830: "12.21",
|
||||||
|
12905909: "12.41",
|
||||||
|
13137020: "12.50",
|
||||||
|
13498980: "12.61",
|
||||||
|
14113327: "13.40",
|
||||||
|
14211474: "14.00",
|
||||||
|
14456520: "14.30",
|
||||||
|
14550713: "14.40",
|
||||||
|
14786821: "14.60",
|
||||||
|
14835335: "15.00",
|
||||||
|
15014719: "15.10",
|
||||||
|
15341163: "15.30",
|
||||||
|
15526472: "15.50",
|
||||||
|
15913292: "16.10",
|
||||||
|
16163563: "16.30",
|
||||||
|
16218553: "16.40",
|
||||||
|
16469788: "16.50",
|
||||||
|
16745144: "17.10",
|
||||||
|
17004569: "17.30",
|
||||||
|
17269705: "17.40",
|
||||||
|
17388565: "17.50",
|
||||||
|
17468642: "18.00",
|
||||||
|
17661844: "18.10",
|
||||||
|
17745267: "18.20",
|
||||||
|
17811397: "18.21",
|
||||||
|
17882303: "18.30",
|
||||||
|
18163738: "18.40",
|
||||||
|
18489740: "19.01",
|
||||||
|
18675304: "19.10",
|
||||||
|
19458861: "20.00",
|
||||||
|
19598943: "20.10",
|
||||||
|
19751212: "20.20",
|
||||||
|
19950687: "20.30",
|
||||||
|
20244966: "20.40",
|
||||||
|
20463113: "21.00",
|
||||||
|
20696680: "21.10",
|
||||||
|
21035704: "21.20",
|
||||||
|
21657658: "21.50",
|
||||||
|
};
|
||||||
|
|
||||||
Future<bool> patchHeadless(File file) async =>
|
Future<bool> patchHeadless(File file) async =>
|
||||||
await _patch(file, _originalHeadless, _patchedHeadless);
|
await _patch(file, _originalHeadless, _patchedHeadless);
|
||||||
|
|
||||||
@@ -179,8 +296,23 @@ String _parseUsername(String username, bool host) {
|
|||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> extractGameVersion(String filePath, String defaultGameVersion) => Isolate.run(() {
|
// Parsing the version is not that easy
|
||||||
final filePathPtr = filePath.toNativeUtf16();
|
// 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
|
||||||
|
// ++Fortnite+Release-34.10-CL-40567068
|
||||||
|
// 4.16.0-3700114+++Fortnite+Release-Cert
|
||||||
|
// 4.19.0-3870737+++Fortnite+Release-Next
|
||||||
|
// 4.20.0-4008490+++Fortnite+Release-3.5
|
||||||
|
Future<String> extractGameVersion(Directory directory) => Isolate.run(() async {
|
||||||
|
log("[VERSION] Looking for $kCrashReportExe in ${directory.path}");
|
||||||
|
final defaultGameVersion = path.basename(directory.path);
|
||||||
|
final crashReportClients = await findFiles(directory, kCrashReportExe);
|
||||||
|
if (crashReportClients.isEmpty) {
|
||||||
|
log("[VERSION] Didn't find a unique match: $crashReportClients");
|
||||||
|
return defaultGameVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("[VERSION] Extracting game version from ${crashReportClients.last.path}(default: $defaultGameVersion)");
|
||||||
|
final filePathPtr = crashReportClients.last.path.toNativeUtf16();
|
||||||
final pPropertyStore = calloc<COMObject>();
|
final pPropertyStore = calloc<COMObject>();
|
||||||
final iidPropertyStore = GUIDFromString(IID_IPropertyStore);
|
final iidPropertyStore = GUIDFromString(IID_IPropertyStore);
|
||||||
final ret = SHGetPropertyStoreFromParsingName(
|
final ret = SHGetPropertyStoreFromParsingName(
|
||||||
@@ -195,8 +327,9 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
|
|||||||
calloc.free(iidPropertyStore);
|
calloc.free(iidPropertyStore);
|
||||||
|
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
|
log("[VERSION] Using default value");
|
||||||
calloc.free(pPropertyStore);
|
calloc.free(pPropertyStore);
|
||||||
throw WindowsException(ret);
|
return defaultGameVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
final propertyStore = IPropertyStore(pPropertyStore);
|
final propertyStore = IPropertyStore(pPropertyStore);
|
||||||
@@ -206,7 +339,8 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
|
|||||||
final count = countPtr.value;
|
final count = countPtr.value;
|
||||||
calloc.free(countPtr);
|
calloc.free(countPtr);
|
||||||
if (FAILED(hrCount)) {
|
if (FAILED(hrCount)) {
|
||||||
throw WindowsException(hrCount);
|
log("[VERSION] Using default value");
|
||||||
|
return defaultGameVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
@@ -222,48 +356,20 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
|
|||||||
if (!FAILED(hrValue)) {
|
if (!FAILED(hrValue)) {
|
||||||
if (pv.ref.vt == VARENUM.VT_LPWSTR) {
|
if (pv.ref.vt == VARENUM.VT_LPWSTR) {
|
||||||
final valueStr = pv.ref.pwszVal.toDartString();
|
final valueStr = pv.ref.pwszVal.toDartString();
|
||||||
if (valueStr.contains("+++Fortnite")) {
|
final headerIndex = valueStr.indexOf("++Fortnite");
|
||||||
var gameVersion = valueStr.substring(valueStr.lastIndexOf("-") + 1);
|
if (headerIndex != -1) {
|
||||||
if(gameVersion == "Cert") {
|
log("[VERSION] Found value string: $valueStr");
|
||||||
|
var gameVersion = valueStr.substring(valueStr.indexOf("-", headerIndex) + 1);
|
||||||
|
log("[VERSION] Game version: $gameVersion");
|
||||||
|
if(gameVersion == "Cert" || gameVersion == "Next") {
|
||||||
final engineVersion = valueStr.substring(0, valueStr.indexOf("+"));
|
final engineVersion = valueStr.substring(0, valueStr.indexOf("+"));
|
||||||
|
log("[VERSION] Engine version: $engineVersion");
|
||||||
final engineVersionParts = engineVersion.split("-");
|
final engineVersionParts = engineVersion.split("-");
|
||||||
final engineVersionBuild = int.parse(engineVersionParts[1]);
|
final engineVersionBuild = int.parse(engineVersionParts[1]);
|
||||||
switch (engineVersionBuild) {
|
log("[VERSION] Engine build: $engineVersionBuild");
|
||||||
case 2870186:
|
gameVersion = _buildToGameVersion[engineVersionBuild] ?? defaultGameVersion;
|
||||||
gameVersion = "OT6.5";
|
|
||||||
break;
|
|
||||||
case 3700114:
|
|
||||||
gameVersion = "1.7.2";
|
|
||||||
break;
|
|
||||||
case 3724489:
|
|
||||||
gameVersion = "1.8.0";
|
|
||||||
break;
|
|
||||||
case 3729133:
|
|
||||||
gameVersion = "1.8.1";
|
|
||||||
break;
|
|
||||||
case 3741772:
|
|
||||||
gameVersion = "1.8.2";
|
|
||||||
break;
|
|
||||||
case 3757339:
|
|
||||||
gameVersion = "1.9";
|
|
||||||
break;
|
|
||||||
case 3775276:
|
|
||||||
gameVersion = "1.9.1";
|
|
||||||
break;
|
|
||||||
case 3790078:
|
|
||||||
gameVersion = "1.10";
|
|
||||||
break;
|
|
||||||
case 3807424:
|
|
||||||
gameVersion = "1.11";
|
|
||||||
break;
|
|
||||||
case 3825894:
|
|
||||||
gameVersion = "2.1";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
gameVersion = defaultGameVersion;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
log("[VERSION] Returning $gameVersion");
|
||||||
return gameVersion;
|
return gameVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,5 +378,6 @@ Future<String> extractGameVersion(String filePath, String defaultGameVersion) =>
|
|||||||
calloc.free(pv);
|
calloc.free(pv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log("[VERSION] Using default value");
|
||||||
return defaultGameVersion;
|
return defaultGameVersion;
|
||||||
});
|
});
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:sync/semaphore.dart';
|
import 'package:synchronized/extension.dart';
|
||||||
|
|
||||||
final File launcherLogFile = _createLoggingFile();
|
final File launcherLogFile = _createLoggingFile();
|
||||||
final Semaphore _semaphore = Semaphore(1);
|
|
||||||
bool enableLoggingToConsole = true;
|
bool enableLoggingToConsole = true;
|
||||||
|
|
||||||
File _createLoggingFile() {
|
File _createLoggingFile() {
|
||||||
@@ -19,14 +18,14 @@ File _createLoggingFile() {
|
|||||||
|
|
||||||
void log(String message) async {
|
void log(String message) async {
|
||||||
try {
|
try {
|
||||||
await _semaphore.acquire();
|
|
||||||
if(enableLoggingToConsole) {
|
if(enableLoggingToConsole) {
|
||||||
print(message);
|
print(message);
|
||||||
}
|
}
|
||||||
await launcherLogFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
|
|
||||||
|
launcherLogFile.synchronized(() async {
|
||||||
|
await launcherLogFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
|
||||||
|
});
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
print("[LOGGER_ERROR] An error occurred while logging: $error");
|
print("[LOGGER_ERROR] An error occurred while logging: $error");
|
||||||
}finally {
|
|
||||||
_semaphore.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ dependencies:
|
|||||||
uuid: ^4.5.1
|
uuid: ^4.5.1
|
||||||
shelf_web_socket: ^2.0.0
|
shelf_web_socket: ^2.0.0
|
||||||
version: ^3.0.2
|
version: ^3.0.2
|
||||||
|
synchronized: ^3.3.0+3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^5.0.0
|
flutter_lints: ^5.0.0
|
||||||
@@ -396,7 +396,7 @@ class BackendController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final version = Get.find<GameController>()
|
final version = Get.find<GameController>()
|
||||||
.getVersionByName(server.version.toString());
|
.getVersionByGame(server.version.toString());
|
||||||
if(version == null) {
|
if(version == null) {
|
||||||
_showRebootInfoBar(
|
_showRebootInfoBar(
|
||||||
translations.cannotJoinServerVersion(server.version.toString()),
|
translations.cannotJoinServerVersion(server.version.toString()),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:get_storage/get_storage.dart';
|
import 'package:get_storage/get_storage.dart';
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_launcher/main.dart';
|
import 'package:reboot_launcher/main.dart';
|
||||||
|
import 'package:version/version.dart';
|
||||||
|
|
||||||
class GameController extends GetxController {
|
class GameController extends GetxController {
|
||||||
static const String storageName = "v3_game_storage";
|
static const String storageName = "v3_game_storage";
|
||||||
@@ -56,6 +57,21 @@ class GameController extends GetxController {
|
|||||||
return versions.value.firstWhereOrNull((element) => element.name == name);
|
return versions.value.firstWhereOrNull((element) => element.name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FortniteVersion? getVersionByGame(String gameVersion) {
|
||||||
|
gameVersion = gameVersion.trim();
|
||||||
|
final parsedGameVersion = Version.parse(gameVersion);
|
||||||
|
return versions.value.firstWhereOrNull((element) {
|
||||||
|
final compare = element.gameVersion.trim();
|
||||||
|
try {
|
||||||
|
final parsedCompare = Version.parse(compare);
|
||||||
|
return parsedCompare.major == parsedGameVersion.major
|
||||||
|
&& parsedCompare.minor == parsedGameVersion.minor;
|
||||||
|
} on FormatException {
|
||||||
|
return compare == gameVersion;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void addVersion(FortniteVersion version) {
|
void addVersion(FortniteVersion version) {
|
||||||
versions.update((val) => val?.add(version));
|
versions.update((val) => val?.add(version));
|
||||||
selectedVersion.value = version;
|
selectedVersion.value = version;
|
||||||
|
|||||||
@@ -47,37 +47,6 @@ Future<String?> openFilePicker(String extension) async {
|
|||||||
bool get isDarkMode =>
|
bool get isDarkMode =>
|
||||||
SchedulerBinding.instance.platformDispatcher.platformBrightness.isDark;
|
SchedulerBinding.instance.platformDispatcher.platformBrightness.isDark;
|
||||||
|
|
||||||
class _ServiceProvider10 extends IUnknown {
|
|
||||||
static const String _CLSID = "{C2F03A33-21F5-47FA-B4BB-156362A2F239}";
|
|
||||||
static const String _IID = "{6D5140C1-7436-11CE-8034-00AA006009FA}";
|
|
||||||
|
|
||||||
_ServiceProvider10._internal(Pointer<COMObject> ptr) : super(ptr);
|
|
||||||
|
|
||||||
factory _ServiceProvider10.createInstance() =>
|
|
||||||
_ServiceProvider10._internal(COMObject.createFromID(_CLSID, _IID));
|
|
||||||
|
|
||||||
Pointer<COMObject> queryService(String classId, String instanceId) {
|
|
||||||
final result = calloc<COMObject>();
|
|
||||||
final code = (ptr.ref.vtable + 3)
|
|
||||||
.cast<
|
|
||||||
Pointer<
|
|
||||||
NativeFunction<
|
|
||||||
HRESULT Function(Pointer, Pointer<GUID>, Pointer<GUID>,
|
|
||||||
Pointer<COMObject>)>>>()
|
|
||||||
.value
|
|
||||||
.asFunction<
|
|
||||||
int Function(Pointer, Pointer<GUID>, Pointer<GUID>,
|
|
||||||
Pointer<COMObject>)>()(ptr.ref.lpVtbl,
|
|
||||||
GUIDFromString(classId), GUIDFromString(instanceId), result);
|
|
||||||
if (code != 0) {
|
|
||||||
free(result);
|
|
||||||
throw WindowsException(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension WindowManagerExtension on WindowManager {
|
extension WindowManagerExtension on WindowManager {
|
||||||
Future<void> maximizeOrRestore() async => await windowManager.isMaximized() ? windowManager.restore() : windowManager.maximize();
|
Future<void> maximizeOrRestore() async => await windowManager.isMaximized() ? windowManager.restore() : windowManager.maximize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/reboot_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/reboot_localizations.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:reboot_common/common.dart';
|
|
||||||
|
|
||||||
AppLocalizations? _translations;
|
AppLocalizations? _translations;
|
||||||
bool _init = false;
|
bool _init = false;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ SettingTile createFileSetting({
|
|||||||
controller: controller,
|
controller: controller,
|
||||||
validator: (text) {
|
validator: (text) {
|
||||||
final result = _checkDll(text);
|
final result = _checkDll(text);
|
||||||
print("Called validator: $result");
|
|
||||||
obx.value = result;
|
obx.value = result;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ class _BrowsePageState extends RebootPageState<BrowsePage> {
|
|||||||
case _Filter.accessible:
|
case _Filter.accessible:
|
||||||
return element.password == null;
|
return element.password == null;
|
||||||
case _Filter.playable:
|
case _Filter.playable:
|
||||||
return _gameController.getVersionByName(element.version) != null;
|
return _gameController.getVersionByGame(element.version) != null;
|
||||||
}
|
}
|
||||||
}).toList();
|
}).toList();
|
||||||
final sort = _sort.value;
|
final sort = _sort.value;
|
||||||
|
|||||||
@@ -147,27 +147,24 @@ class _ImportVersionDialogState extends State<ImportVersionDialog> {
|
|||||||
final name = _nameController.text.trim();
|
final name = _nameController.text.trim();
|
||||||
final directory = Directory(_pathController.text.trim());
|
final directory = Directory(_pathController.text.trim());
|
||||||
|
|
||||||
final files = await Future.wait([
|
final shippingExes = await Future.wait([
|
||||||
Future.delayed(const Duration(seconds: 1)).then((_) => <File>[]),
|
Future.delayed(const Duration(seconds: 1)).then((_) => <File>[]),
|
||||||
findFiles(directory, kShippingExe).then((files) async {
|
findFiles(directory, kShippingExe)
|
||||||
if(files.length == 1) {
|
|
||||||
await patchHeadless(files.first);
|
|
||||||
}
|
|
||||||
return files;
|
|
||||||
})
|
|
||||||
]).then((values) => values.expand((entry) => entry).toList());
|
]).then((values) => values.expand((entry) => entry).toList());
|
||||||
|
|
||||||
if (files.isEmpty) {
|
if (shippingExes.isEmpty) {
|
||||||
_validator.value = _ImportState.missingShippingExeError;
|
_validator.value = _ImportState.missingShippingExeError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(files.length != 1) {
|
if(shippingExes.length != 1) {
|
||||||
_validator.value = _ImportState.multipleShippingExesError;
|
_validator.value = _ImportState.multipleShippingExesError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final gameVersion = await extractGameVersion(files.first.path, path.basename(directory.path));
|
await patchHeadless(shippingExes.first);
|
||||||
|
|
||||||
|
final gameVersion = await extractGameVersion(directory);
|
||||||
try {
|
try {
|
||||||
if(Version.parse(gameVersion) >= kMaxAllowedVersion) {
|
if(Version.parse(gameVersion) >= kMaxAllowedVersion) {
|
||||||
_validator.value = _ImportState.unsupportedVersionError;
|
_validator.value = _ImportState.unsupportedVersionError;
|
||||||
@@ -181,13 +178,13 @@ class _ImportVersionDialogState extends State<ImportVersionDialog> {
|
|||||||
final version = FortniteVersion(
|
final version = FortniteVersion(
|
||||||
name: name,
|
name: name,
|
||||||
gameVersion: gameVersion,
|
gameVersion: gameVersion,
|
||||||
location: files.first.parent
|
location: shippingExes.first.parent
|
||||||
);
|
);
|
||||||
_gameController.addVersion(version);
|
_gameController.addVersion(version);
|
||||||
}else {
|
}else {
|
||||||
widget.version?.name = name;
|
widget.version?.name = name;
|
||||||
widget.version?.gameVersion = gameVersion;
|
widget.version?.gameVersion = gameVersion;
|
||||||
widget.version?.location = files.first.parent;
|
widget.version?.location = shippingExes.first.parent;
|
||||||
}
|
}
|
||||||
_validator.value = _ImportState.success;
|
_validator.value = _ImportState.success;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user