mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 19:22:22 +01:00
<feat: New project structure>
<feat: New release>
This commit is contained in:
85
gui/lib/src/util/checks.dart
Normal file
85
gui/lib/src/util/checks.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:reboot_common/common.dart';
|
||||
|
||||
String? checkVersion(String? text, List<FortniteVersion> versions) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return 'Empty version name';
|
||||
}
|
||||
|
||||
if (versions.any((element) => element.name == text)) {
|
||||
return 'This version already exists';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String? checkChangeVersion(String? text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return 'Empty version name';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String? checkGameFolder(text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return 'Empty game path';
|
||||
}
|
||||
|
||||
var directory = Directory(text);
|
||||
if (!directory.existsSync()) {
|
||||
return "Directory doesn't exist";
|
||||
}
|
||||
|
||||
if (FortniteVersionExtension.findExecutable(directory, "FortniteClient-Win64-Shipping.exe") == null) {
|
||||
return "Invalid game path";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String? checkDownloadDestination(text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return 'Invalid download path';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String? checkDll(String? text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return "Empty dll path";
|
||||
}
|
||||
|
||||
if (!File(text).existsSync()) {
|
||||
return "This dll doesn't exist";
|
||||
}
|
||||
|
||||
if (!text.endsWith(".dll")) {
|
||||
return "This file is not a dll";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String? checkMatchmaking(String? text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return "Empty hostname";
|
||||
}
|
||||
|
||||
var ipParts = text.split(":");
|
||||
if(ipParts.length > 2){
|
||||
return "Wrong format, expected ip:port";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String? checkUpdateUrl(String? text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return "Empty URL";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
52
gui/lib/src/util/cryptography.dart
Normal file
52
gui/lib/src/util/cryptography.dart
Normal file
@@ -0,0 +1,52 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:bcrypt/bcrypt.dart';
|
||||
import 'package:pointycastle/export.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
const int _ivLength = 16;
|
||||
const int _keyLength = 32;
|
||||
|
||||
String hashPassword(String plaintext) => BCrypt.hashpw(plaintext, BCrypt.gensalt());
|
||||
|
||||
bool checkPassword(String password, String hashedText) => BCrypt.checkpw(password, hashedText);
|
||||
|
||||
String aes256Encrypt(String plainText, String password) {
|
||||
final random = Random.secure();
|
||||
final iv = Uint8List.fromList(List.generate(_ivLength, (index) => random.nextInt(256)));
|
||||
final keyDerivationData = Uint8List.fromList(utf8.encode(password));
|
||||
final derive = PBKDF2KeyDerivator(HMac(SHA256Digest(), _ivLength * 8));
|
||||
var params = Pbkdf2Parameters(iv, _ivLength * 8, _keyLength);
|
||||
derive.init(params);
|
||||
final key = derive.process(keyDerivationData);
|
||||
final cipherParams = PaddedBlockCipherParameters(
|
||||
KeyParameter(key),
|
||||
null,
|
||||
);
|
||||
final aes = AESEngine();
|
||||
final paddingCipher = PaddedBlockCipherImpl(PKCS7Padding(), aes);
|
||||
paddingCipher.init(true, cipherParams);
|
||||
final plainBytes = Uint8List.fromList(utf8.encode(plainText));
|
||||
final encryptedBytes = paddingCipher.process(plainBytes);
|
||||
return base64.encode([...iv, ...encryptedBytes]);
|
||||
}
|
||||
|
||||
String aes256Decrypt(String encryptedText, String password) {
|
||||
final encryptedBytes = base64.decode(encryptedText);
|
||||
final salt = encryptedBytes.sublist(0, _ivLength);
|
||||
final payload = encryptedBytes.sublist(_ivLength);
|
||||
final keyDerivationData = Uint8List.fromList(utf8.encode(password));
|
||||
final derive = PBKDF2KeyDerivator(HMac(SHA256Digest(), _ivLength * 8));
|
||||
var params = Pbkdf2Parameters(salt, _ivLength * 8, _keyLength);
|
||||
derive.init(params);
|
||||
final key = derive.process(keyDerivationData);
|
||||
final cipherParams = PaddedBlockCipherParameters(
|
||||
KeyParameter(key),
|
||||
null,
|
||||
);
|
||||
final aes = AESEngine();
|
||||
final paddingCipher = PaddedBlockCipherImpl(PKCS7Padding(), aes);
|
||||
paddingCipher.init(false, cipherParams);
|
||||
final decryptedBytes = paddingCipher.process(payload);
|
||||
return utf8.decode(decryptedBytes);
|
||||
}
|
||||
13
gui/lib/src/util/os.dart
Normal file
13
gui/lib/src/util/os.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'dart:io';
|
||||
|
||||
final RegExp _winBuildRegex = RegExp(r'(?<=\(Build )(.*)(?=\))');
|
||||
|
||||
bool get isWin11 {
|
||||
var result = _winBuildRegex.firstMatch(Platform.operatingSystemVersion)?.group(1);
|
||||
if(result == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
var intBuild = int.tryParse(result);
|
||||
return intBuild != null && intBuild > 22000;
|
||||
}
|
||||
17
gui/lib/src/util/picker.dart
Normal file
17
gui/lib/src/util/picker.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
Future<String?> openFolderPicker(String title) async =>
|
||||
await FilePicker.platform.getDirectoryPath(dialogTitle: title);
|
||||
|
||||
Future<String?> openFilePicker(String extension) async {
|
||||
var result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowMultiple: false,
|
||||
allowedExtensions: [extension]
|
||||
);
|
||||
if(result == null || result.files.isEmpty){
|
||||
return null;
|
||||
}
|
||||
|
||||
return result.files.first.path;
|
||||
}
|
||||
48
gui/lib/src/util/watch.dart
Normal file
48
gui/lib/src/util/watch.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
final SupabaseClient _supabase = Supabase.instance.client;
|
||||
final GameController _gameController = Get.find<GameController>();
|
||||
final HostingController _hostingController = Get.find<HostingController>();
|
||||
|
||||
extension GameInstanceWatcher on GameInstance {
|
||||
Future<void> startObserver() async {
|
||||
if(watchPid != null) {
|
||||
Process.killPid(watchPid!, ProcessSignal.sigabrt);
|
||||
}
|
||||
|
||||
watchProcess(gamePid).then((value) async {
|
||||
if(hosting) {
|
||||
_onHostingStopped();
|
||||
}
|
||||
|
||||
_onGameStopped();
|
||||
});
|
||||
|
||||
watchPid = startBackgroundProcess(
|
||||
'${assetsDirectory.path}\\misc\\watch.exe',
|
||||
[_gameController.uuid, gamePid.toString(), launcherPid?.toString() ?? "-1", eacPid?.toString() ?? "-1", hosting.toString()]
|
||||
);
|
||||
}
|
||||
|
||||
void _onGameStopped() {
|
||||
_gameController.started.value = false;
|
||||
_gameController.instance.value?.kill();
|
||||
if(linkedHosting) {
|
||||
_onHostingStopped();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onHostingStopped() async {
|
||||
_hostingController.started.value = false;
|
||||
_hostingController.instance.value?.kill();
|
||||
await _supabase.from('hosts')
|
||||
.delete()
|
||||
.match({'id': _gameController.uuid});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user