Release 9.2.0

This commit is contained in:
Alessandro Autiero
2024-07-06 18:43:52 +02:00
parent 45b8629207
commit e3b8d7d182
91 changed files with 3871 additions and 3132 deletions

View File

@@ -1,86 +0,0 @@
import 'dart:io';
import 'package:reboot_common/common.dart';
import 'package:reboot_launcher/src/util/translations.dart';
String? checkVersion(String? text, List<FortniteVersion> versions) {
if (text == null || text.isEmpty) {
return translations.emptyVersionName;
}
if (versions.any((element) => element.name == text)) {
return translations.versionAlreadyExists;
}
return null;
}
String? checkChangeVersion(String? text) {
if (text == null || text.isEmpty) {
return translations.emptyVersionName;
}
return null;
}
String? checkGameFolder(text) {
if (text == null || text.isEmpty) {
return translations.emptyGamePath;
}
var directory = Directory(text);
if (!directory.existsSync()) {
return translations.directoryDoesNotExist;
}
if (FortniteVersionExtension.findExecutable(directory, "FortniteClient-Win64-Shipping.exe") == null) {
return translations.missingShippingExe;
}
return null;
}
String? checkDownloadDestination(text) {
if (text == null || text.isEmpty) {
return translations.invalidDownloadPath;
}
return null;
}
String? checkDll(String? text) {
if (text == null || text.isEmpty) {
return translations.invalidDllPath;
}
if (!File(text).existsSync()) {
return translations.dllDoesNotExist;
}
if (!text.endsWith(".dll")) {
return translations.invalidDllExtension;
}
return null;
}
String? checkMatchmaking(String? text) {
if (text == null || text.isEmpty) {
return translations.emptyHostname;
}
var ipParts = text.split(":");
if(ipParts.length > 2){
return translations.hostnameFormat;
}
return null;
}
String? checkUpdateUrl(String? text) {
if (text == null || text.isEmpty) {
return translations.emptyURL;
}
return null;
}

View File

@@ -1,107 +0,0 @@
import 'dart:async';
import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
import 'package:reboot_launcher/src/controller/settings_controller.dart';
import 'package:reboot_launcher/src/controller/update_controller.dart';
import 'package:reboot_launcher/src/dialog/abstract/info_bar.dart';
import 'package:reboot_launcher/src/util/translations.dart';
final UpdateController _updateController = Get.find<UpdateController>();
final Map<String, Future<void>> _operations = {};
Future<void> downloadCriticalDllInteractive(String filePath, {bool silent = false}) {
final old = _operations[filePath];
if(old != null) {
return old;
}
final newRun = _downloadCriticalDllInteractive(filePath, silent);
_operations[filePath] = newRun;
return newRun;
}
Future<void> _downloadCriticalDllInteractive(String filePath, bool silent) async {
final fileName = path.basename(filePath).toLowerCase();
InfoBarEntry? entry;
try {
if (fileName == "reboot.dll") {
await _updateController.updateReboot(
silent: silent
);
return;
}
if(File(filePath).existsSync()) {
return;
}
final fileNameWithoutExtension = path.basenameWithoutExtension(filePath);
if(!silent) {
entry = showInfoBar(
translations.downloadingDll(fileNameWithoutExtension),
loading: true,
duration: null
);
}
await downloadCriticalDll(fileName, filePath);
entry?.close();
if(!silent) {
entry = await showInfoBar(
translations.downloadDllSuccess(fileNameWithoutExtension),
severity: InfoBarSeverity.success,
duration: infoBarShortDuration
);
}
}catch(message) {
if(!silent) {
entry?.close();
var error = message.toString();
error = error.contains(": ") ? error.substring(error.indexOf(": ") + 2) : error;
error = error.toLowerCase();
final completer = Completer();
await showInfoBar(
translations.downloadDllError(fileName, error.toString()),
duration: infoBarLongDuration,
severity: InfoBarSeverity.error,
onDismissed: () => completer.complete(null),
action: Button(
onPressed: () async {
await downloadCriticalDllInteractive(filePath);
completer.complete(null);
},
child: Text(translations.downloadDllRetry),
)
);
await completer.future;
}
}finally {
_operations.remove(fileName);
}
}
extension InjectableDllExtension on InjectableDll {
String get path {
final SettingsController settingsController = Get.find<SettingsController>();
switch(this){
case InjectableDll.reboot:
if(_updateController.customGameServer.value) {
final file = File(settingsController.gameServerDll.text);
if(file.existsSync()) {
return file.path;
}
}
return rebootDllFile.path;
case InjectableDll.console:
return settingsController.unrealEngineConsoleDll.text;
case InjectableDll.cobalt:
return settingsController.backendDll.text;
case InjectableDll.memory:
return settingsController.memoryLeakDll.text;
}
}
}

View File

@@ -1,29 +0,0 @@
import 'dart:io';
import 'package:reboot_common/common.dart';
import 'package:sync/semaphore.dart';
final File _loggingFile = _createLoggingFile();
final Semaphore _semaphore = Semaphore(1);
File _createLoggingFile() {
final file = File("${logsDirectory.path}\\launcher.log");
file.parent.createSync(recursive: true);
if(file.existsSync()) {
file.deleteSync();
}
file.createSync();
return file;
}
void log(String message) async {
try {
await _semaphore.acquire();
print(message);
await _loggingFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
}catch(error) {
print(error);
}finally {
_semaphore.release();
}
}

View File

@@ -3,45 +3,52 @@ import 'dart:io';
import 'package:reboot_common/common.dart';
const Duration _timeout = Duration(seconds: 2);
Future<bool> _pingGameServer(String hostname, int port) async {
RawDatagramSocket? socket;
try {
socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
final dataToSend = utf8.encode(DateTime.now().toIso8601String());
socket.send(dataToSend, InternetAddress(hostname), port);
await for (var event in socket) {
switch(event) {
case RawSocketEvent.read:
case RawSocketEvent.write:
return true;
case RawSocketEvent.readClosed:
case RawSocketEvent.closed:
return false;
}
}
return false;
}finally {
socket?.close();
}
}
Future<bool> get _timeoutFuture => Future.delayed(_timeout).then((value) => false);
const Duration _timeout = Duration(seconds: 5);
Future<bool> pingGameServer(String address, {Duration? timeout}) async {
var start = DateTime.now();
var firstTime = true;
while (firstTime || (timeout != null && DateTime.now().millisecondsSinceEpoch - start.millisecondsSinceEpoch < timeout.inMilliseconds)) {
var split = address.split(":");
var hostname = split[0];
if(isLocalHost(hostname)) {
hostname = "127.0.0.1";
}
Future<bool> ping(String hostname, int port) async {
log("[MATCHMAKER] Pinging $hostname:$port");
RawDatagramSocket? socket;
try {
socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
await for (final event in socket) {
log("[MATCHMAKER] Event: $event");
switch(event) {
case RawSocketEvent.read:
log("[MATCHMAKER] Success");
return true;
case RawSocketEvent.write:
log("[MATCHMAKER] Sending data");
final dataToSend = base64Decode("AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA==");
socket.send(dataToSend, InternetAddress(hostname), port);
case RawSocketEvent.readClosed:
case RawSocketEvent.closed:
return false;
}
}
var port = int.parse(split.length > 1 ? split[1] : kDefaultGameServerPort);
var result = await Future.any([_timeoutFuture, _pingGameServer(hostname, port)]);
return false;
}catch(error) {
log("[MATCHMAKER] Error: $error");
return false;
}finally {
socket?.close();
}
}
final start = DateTime.now();
var firstTime = true;
final split = address.split(":");
var hostname = split[0];
if(isLocalHost(hostname)) {
hostname = "127.0.0.1";
}
final port = int.parse(split.length > 1 ? split[1] : kDefaultGameServerPort);
while (firstTime || (timeout != null && DateTime.now().millisecondsSinceEpoch - start.millisecondsSinceEpoch < timeout.inMilliseconds)) {
final result = await ping(hostname, port)
.timeout(_timeout, onTimeout: () => false);
if(result) {
return true;
}

View File

@@ -3,10 +3,10 @@ import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:file_picker/file_picker.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/scheduler.dart';
import 'package:win32/win32.dart';
import 'package:file_picker/file_picker.dart';
final RegExp _winBuildRegex = RegExp(r'(?<=\(Build )(.*)(?=\))');