mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 03:02:22 +01:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cfa4af236 | ||
|
|
d42946c44b | ||
|
|
0a59a32c1b |
@@ -134,17 +134,13 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _startAriaServer() async {
|
Future<void> _startAriaServer() async {
|
||||||
final running = await _isAriaRunning();
|
await stopDownloadServer();
|
||||||
if(running) {
|
|
||||||
await killProcessByPort(_ariaPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
final aria2c = File("${assetsDirectory.path}\\build\\aria2c.exe");
|
final aria2c = File("${assetsDirectory.path}\\build\\aria2c.exe");
|
||||||
if(!aria2c.existsSync()) {
|
if(!aria2c.existsSync()) {
|
||||||
throw "Missing aria2c.exe";
|
throw "Missing aria2c.exe";
|
||||||
}
|
}
|
||||||
|
|
||||||
await startProcess(
|
final process = await startProcess(
|
||||||
executable: aria2c,
|
executable: aria2c,
|
||||||
args: [
|
args: [
|
||||||
"--max-connection-per-server=${Platform.numberOfProcessors}",
|
"--max-connection-per-server=${Platform.numberOfProcessors}",
|
||||||
@@ -153,10 +149,14 @@ Future<void> _startAriaServer() async {
|
|||||||
"--rpc-listen-all=true",
|
"--rpc-listen-all=true",
|
||||||
"--rpc-allow-origin-all",
|
"--rpc-allow-origin-all",
|
||||||
"--rpc-secret=$_ariaSecret",
|
"--rpc-secret=$_ariaSecret",
|
||||||
"--rpc-listen-port=$_ariaPort"
|
"--rpc-listen-port=$_ariaPort",
|
||||||
|
"--file-allocation=none"
|
||||||
],
|
],
|
||||||
window: false
|
window: false
|
||||||
);
|
);
|
||||||
|
process.stdOutput.listen((message) => log("[ARIA] Message: $message"));
|
||||||
|
process.stdError.listen((error) => log("[ARIA] Error: $error"));
|
||||||
|
process.exitCode.then((exitCode) => log("[ARIA] Exit code: $exitCode"));
|
||||||
for(var i = 0; i < _ariaMaxSpawnTime.inSeconds; i++) {
|
for(var i = 0; i < _ariaMaxSpawnTime.inSeconds; i++) {
|
||||||
if(await _isAriaRunning()) {
|
if(await _isAriaRunning()) {
|
||||||
return;
|
return;
|
||||||
@@ -177,8 +177,8 @@ Future<bool> _isAriaRunning() async {
|
|||||||
"token:${_ariaSecret}"
|
"token:${_ariaSecret}"
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
await http.post(_ariaEndpoint, body: jsonEncode(statusRequest));
|
final response = await http.post(_ariaEndpoint, body: jsonEncode(statusRequest));
|
||||||
return true;
|
return response.statusCode == 200;
|
||||||
}catch(_) {
|
}catch(_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -227,11 +227,16 @@ Future<void> _stopAriaDownload(String downloadId) async {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
await http.post(_ariaEndpoint, body: jsonEncode(addDownloadRequest));
|
await http.post(_ariaEndpoint, body: jsonEncode(addDownloadRequest));
|
||||||
|
stopDownloadServer();
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
throw "Stop failed (${error})";
|
throw "Stop failed (${error})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> stopDownloadServer() async {
|
||||||
|
await killProcessByPort(_ariaPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
|
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
|
||||||
Process? process;
|
Process? process;
|
||||||
|
|||||||
@@ -216,7 +216,6 @@
|
|||||||
"downloadedVersion": "The download was completed successfully!",
|
"downloadedVersion": "The download was completed successfully!",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"downloading": "Downloading...",
|
"downloading": "Downloading...",
|
||||||
"allocatingSpace": "Allocating disk space...",
|
|
||||||
"startingDownload": "Starting download...",
|
"startingDownload": "Starting download...",
|
||||||
"extracting": "Extracting...",
|
"extracting": "Extracting...",
|
||||||
"buildProgress": "{progress}%",
|
"buildProgress": "{progress}%",
|
||||||
@@ -237,7 +236,7 @@
|
|||||||
"startGame": "Start fortnite",
|
"startGame": "Start fortnite",
|
||||||
"stopGame": "Close fortnite",
|
"stopGame": "Close fortnite",
|
||||||
"waitingForGameServer": "Waiting for the game server to boot up...",
|
"waitingForGameServer": "Waiting for the game server to boot up...",
|
||||||
"gameServerStartWarning": "The game server was started successfully, but Reboot didn't load",
|
"gameServerStartWarning": "Unsupported version: the game server crashed while setting up the server",
|
||||||
"gameServerStartLocalWarning": "The game server was started successfully, but other players can't join",
|
"gameServerStartLocalWarning": "The game server was started successfully, but other players can't join",
|
||||||
"gameServerStarted": "The game server was started successfully",
|
"gameServerStarted": "The game server was started successfully",
|
||||||
"gameClientStarted": "The game client was started successfully",
|
"gameClientStarted": "The game client was started successfully",
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ Future<void> _initWindow() async {
|
|||||||
await windowManager.setAlignment(Alignment.center);
|
await windowManager.setAlignment(Alignment.center);
|
||||||
}
|
}
|
||||||
await windowManager.setPreventClose(true);
|
await windowManager.setPreventClose(true);
|
||||||
|
await windowManager.setResizable(true);
|
||||||
if(isWin11) {
|
if(isWin11) {
|
||||||
await Window.setEffect(
|
await Window.setEffect(
|
||||||
effect: WindowEffect.acrylic,
|
effect: WindowEffect.acrylic,
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import 'package:get/get.dart';
|
|||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
import 'package:reboot_launcher/src/util/translations.dart';
|
import 'package:reboot_launcher/src/util/translations.dart';
|
||||||
import 'package:reboot_launcher/src/util/types.dart';
|
import 'package:reboot_launcher/src/util/types.dart';
|
||||||
import 'package:reboot_launcher/src/widget/file_selector.dart';
|
import 'package:reboot_launcher/src/widget/file_selector.dart';
|
||||||
import 'package:universal_disk_space/universal_disk_space.dart';
|
|
||||||
import 'package:windows_taskbar/windows_taskbar.dart';
|
import 'package:windows_taskbar/windows_taskbar.dart';
|
||||||
|
|
||||||
class AddVersionDialog extends StatefulWidget {
|
class AddVersionDialog extends StatefulWidget {
|
||||||
@@ -35,9 +35,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
final Rxn<double> _progress = Rxn();
|
final Rxn<double> _progress = Rxn();
|
||||||
final RxInt _speed = RxInt(0);
|
final RxInt _speed = RxInt(0);
|
||||||
|
|
||||||
late DiskSpace _diskSpace;
|
|
||||||
late Future<List<FortniteBuild>> _fetchFuture;
|
late Future<List<FortniteBuild>> _fetchFuture;
|
||||||
late Future _diskFuture;
|
|
||||||
|
|
||||||
SendPort? _downloadPort;
|
SendPort? _downloadPort;
|
||||||
Object? _error;
|
Object? _error;
|
||||||
@@ -45,10 +43,10 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_fetchFuture = compute(fetchBuilds, null);
|
_fetchFuture = compute(fetchBuilds, null).then((value) {
|
||||||
_diskSpace = DiskSpace();
|
_updateFormDefaults();
|
||||||
_diskFuture = _diskSpace.scan()
|
return value;
|
||||||
.then((_) => _updateFormDefaults());
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
switch(_status.value){
|
switch(_status.value){
|
||||||
case _DownloadStatus.form:
|
case _DownloadStatus.form:
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: Future.wait([_fetchFuture, _diskFuture]).then((_) async => await _fetchFuture),
|
future: _fetchFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => _onDownloadError(snapshot.error, snapshot.stackTrace));
|
WidgetsBinding.instance.addPostFrameCallback((_) => _onDownloadError(snapshot.error, snapshot.stackTrace));
|
||||||
@@ -244,12 +242,12 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if(_progress.value != null && !_isAllocatingDiskSpace)
|
if(_progress.value != null)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8.0,
|
height: 8.0,
|
||||||
),
|
),
|
||||||
|
|
||||||
if(_progress.value != null && !_isAllocatingDiskSpace)
|
if(_progress.value != null)
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@@ -272,7 +270,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ProgressBar(value: _isAllocatingDiskSpace ? null : _progress.value?.toDouble())
|
child: ProgressBar(value: _progress.value?.toDouble())
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@@ -291,15 +289,9 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
return translations.startingDownload;
|
return translations.startingDownload;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_speed.value == 0) {
|
|
||||||
return translations.allocatingSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
return translations.downloading;
|
return translations.downloading;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get _isAllocatingDiskSpace => _status.value == _DownloadStatus.downloading && _speed.value == 0;
|
|
||||||
|
|
||||||
Widget _buildFormBody(List<FortniteBuild> builds) {
|
Widget _buildFormBody(List<FortniteBuild> builds) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@@ -450,16 +442,16 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
_build.value = null;
|
_build.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_source.value != _BuildSource.local && _diskSpace.disks.isNotEmpty) {
|
final disks = WindowsDisk.available();
|
||||||
await _fetchFuture;
|
if(_source.value != _BuildSource.local && disks.isNotEmpty) {
|
||||||
final bestDisk = _diskSpace.disks
|
final bestDisk = disks.reduce((first, second) => first.freeBytesAvailable > second.freeBytesAvailable ? first : second);
|
||||||
.reduce((first, second) => first.availableSpace > second.availableSpace ? first : second);
|
|
||||||
final build = _build.value;
|
final build = _build.value;
|
||||||
if(build == null){
|
if(build == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final pathText = "${bestDisk.devicePath}\\FortniteBuilds\\${build.version}";
|
print("${bestDisk.path}\\FortniteBuilds\\${build.version}");
|
||||||
|
final pathText = "${bestDisk.path}FortniteBuilds\\${build.version}";
|
||||||
_pathController.text = pathText;
|
_pathController.text = pathText;
|
||||||
_pathController.selection = TextSelection.collapsed(offset: pathText.length);
|
_pathController.selection = TextSelection.collapsed(offset: pathText.length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_launcher/src/controller/backend_controller.dart';
|
import 'package:reboot_launcher/src/controller/backend_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/dll_controller.dart';
|
import 'package:reboot_launcher/src/controller/dll_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
||||||
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
||||||
@@ -43,6 +44,7 @@ class HomePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepAliveClientMixin {
|
class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepAliveClientMixin {
|
||||||
final BackendController _backendController = Get.find<BackendController>();
|
final BackendController _backendController = Get.find<BackendController>();
|
||||||
|
final GameController _gameController = Get.find<GameController>();
|
||||||
final HostingController _hostingController = Get.find<HostingController>();
|
final HostingController _hostingController = Get.find<HostingController>();
|
||||||
final SettingsController _settingsController = Get.find<SettingsController>();
|
final SettingsController _settingsController = Get.find<SettingsController>();
|
||||||
final DllController _dllController = Get.find<DllController>();
|
final DllController _dllController = Get.find<DllController>();
|
||||||
@@ -160,14 +162,45 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onWindowClose() async {
|
void onWindowClose() async {
|
||||||
|
try {
|
||||||
|
await windowManager.hide();
|
||||||
|
}catch(error) {
|
||||||
|
log("[WINDOW] Cannot hide window: $error");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await _hostingController.discardServer();
|
await _hostingController.discardServer();
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
log("[HOSTING] Cannot discard server: $error");
|
log("[HOSTING] Cannot discard server on exit: $error");
|
||||||
}finally {
|
|
||||||
// Force closing because the backend might be running, but we want the process to exit
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(_backendController.started.value) {
|
||||||
|
await _backendController.toggleInteractive();
|
||||||
|
}
|
||||||
|
}catch(error) {
|
||||||
|
log("[BACKEND] Cannot stop backend on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_gameController.instance.value?.kill();
|
||||||
|
}catch(error) {
|
||||||
|
log("[GAME] Cannot stop game on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_hostingController.instance.value?.kill();
|
||||||
|
}catch(error) {
|
||||||
|
log("[HOST] Cannot stop host on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await stopDownloadServer();
|
||||||
|
}catch(error) {
|
||||||
|
log("[ARIA] Cannot stop aria server on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
|
|
||||||
@@ -9,22 +10,24 @@ const Duration _timeout = Duration(seconds: 5);
|
|||||||
Completer<bool> pingGameServerOrTimeout(String address, Duration timeout) {
|
Completer<bool> pingGameServerOrTimeout(String address, Duration timeout) {
|
||||||
final completer = Completer<bool>();
|
final completer = Completer<bool>();
|
||||||
final start = DateTime.now();
|
final start = DateTime.now();
|
||||||
(() async {
|
_pingGameServerOrTimeout(completer, start, timeout, address);
|
||||||
while (!completer.isCompleted && DateTime.now().millisecondsSinceEpoch - start.millisecondsSinceEpoch < timeout.inMilliseconds) {
|
|
||||||
final result = await pingGameServer(address);
|
|
||||||
if(result) {
|
|
||||||
completer.complete(true);
|
|
||||||
}else {
|
|
||||||
await Future.delayed(_timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!completer.isCompleted) {
|
|
||||||
completer.complete(false);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
return completer;
|
return completer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _pingGameServerOrTimeout(Completer<bool> completer, DateTime start, Duration timeout, String address) async {
|
||||||
|
while (!completer.isCompleted && max(DateTime.now().millisecondsSinceEpoch - start.millisecondsSinceEpoch, 0) < timeout.inMilliseconds) {
|
||||||
|
final result = await pingGameServer(address);
|
||||||
|
if(result) {
|
||||||
|
completer.complete(true);
|
||||||
|
}else {
|
||||||
|
await Future.delayed(_timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!completer.isCompleted) {
|
||||||
|
completer.complete(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> pingGameServer(String address) async {
|
Future<bool> pingGameServer(String address) async {
|
||||||
final split = address.split(":");
|
final split = address.split(":");
|
||||||
var hostname = split[0];
|
var hostname = split[0];
|
||||||
|
|||||||
@@ -492,3 +492,57 @@ int _convertToHString(String string) {
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WindowsDisk {
|
||||||
|
static final String _nullTerminator = String.fromCharCode(0);
|
||||||
|
|
||||||
|
final String path;
|
||||||
|
final int freeBytesAvailable;
|
||||||
|
final int totalNumberOfBytes;
|
||||||
|
|
||||||
|
const WindowsDisk._internal(this.path, this.freeBytesAvailable, this.totalNumberOfBytes);
|
||||||
|
|
||||||
|
static List<WindowsDisk> available() {
|
||||||
|
final buffer = malloc.allocate<Utf16>(MAX_PATH);
|
||||||
|
try {
|
||||||
|
final length = GetLogicalDriveStrings(MAX_PATH, buffer);
|
||||||
|
if (length == 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toDartString(length: length)
|
||||||
|
.split(_nullTerminator)
|
||||||
|
.where((drive) => drive.length > 1)
|
||||||
|
.map((driveName) {
|
||||||
|
final freeBytesAvailable = calloc<Uint64>();
|
||||||
|
final totalNumberOfBytes = calloc<Uint64>();
|
||||||
|
final totalNumberOfFreeBytes = calloc<Uint64>();
|
||||||
|
try {
|
||||||
|
GetDiskFreeSpaceEx(
|
||||||
|
driveName.toNativeUtf16(),
|
||||||
|
freeBytesAvailable,
|
||||||
|
totalNumberOfBytes,
|
||||||
|
totalNumberOfFreeBytes
|
||||||
|
);
|
||||||
|
return WindowsDisk._internal(
|
||||||
|
driveName,
|
||||||
|
freeBytesAvailable.value,
|
||||||
|
totalNumberOfBytes.value
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
calloc.free(freeBytesAvailable);
|
||||||
|
calloc.free(totalNumberOfBytes);
|
||||||
|
calloc.free(totalNumberOfFreeBytes);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toList(growable: false);
|
||||||
|
} finally {
|
||||||
|
calloc.free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'WindowsDisk{path: $path, freeBytesAvailable: $freeBytesAvailable, totalNumberOfBytes: $totalNumberOfBytes}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -492,7 +492,7 @@ class _LaunchButtonState extends State<LaunchButton> {
|
|||||||
|
|
||||||
final pingOperation = pingGameServerOrTimeout(
|
final pingOperation = pingGameServerOrTimeout(
|
||||||
"$publicIp:$gameServerPort",
|
"$publicIp:$gameServerPort",
|
||||||
const Duration(days: 365)
|
const Duration(days: 1)
|
||||||
);
|
);
|
||||||
this._pingOperation = pingOperation;
|
this._pingOperation = pingOperation;
|
||||||
_gameServerInfoBar = showRebootInfoBar(
|
_gameServerInfoBar = showRebootInfoBar(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: reboot_launcher
|
name: reboot_launcher
|
||||||
description: Graphical User Interface for Project Reboot
|
description: Graphical User Interface for Project Reboot
|
||||||
version: "10.0.1"
|
version: "10.0.4"
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
@@ -58,7 +58,6 @@ dependencies:
|
|||||||
|
|
||||||
# Storage
|
# Storage
|
||||||
get_storage: ^2.1.1
|
get_storage: ^2.1.1
|
||||||
universal_disk_space: ^0.2.3
|
|
||||||
path: ^1.9.0
|
path: ^1.9.0
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ Source: "{{SOURCE_DIR}}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdir
|
|||||||
Source: "..\..\dependencies\redist\VC_redist.x64.exe"; DestDir: {tmp}; Flags: dontcopy
|
Source: "..\..\dependencies\redist\VC_redist.x64.exe"; DestDir: {tmp}; Flags: dontcopy
|
||||||
|
|
||||||
[Run]
|
[Run]
|
||||||
Filename: "powershell.exe"; Parameters: "-ExecutionPolicy Bypass -Command ""Add-MpPreference -ExclusionPath '{app}'"""; Flags: runhidden
|
|
||||||
Filename: "{app}\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: runascurrentuser nowait postinstall skipifsilent
|
Filename: "{app}\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: runascurrentuser nowait postinstall skipifsilent
|
||||||
Filename: "{tmp}\VC_redist.x64.exe"; StatusMsg: "{cm:InstallingVC2017redist}"; Parameters: "/quiet"; Check: VC2017RedistNeedsInstall; Flags: waituntilterminated
|
Filename: "{tmp}\VC_redist.x64.exe"; StatusMsg: "{cm:InstallingVC2017redist}"; Parameters: "/quiet"; Check: VC2017RedistNeedsInstall; Flags: waituntilterminated
|
||||||
|
|
||||||
@@ -46,6 +45,44 @@ Name: "{autodesktop}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; T
|
|||||||
Name: "{userstartup}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup
|
Name: "{userstartup}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup
|
||||||
|
|
||||||
[Code]
|
[Code]
|
||||||
|
var
|
||||||
|
Page: TInputOptionWizardPage;
|
||||||
|
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
Page := CreateInputOptionPage(
|
||||||
|
wpWelcome,
|
||||||
|
' Allow DLL injection',
|
||||||
|
' The Reboot Launcher needs to inject DLLs into Fortnite to create the game server',
|
||||||
|
'Selecting the option below will add the Reboot Launcher to the Windows Exclusions list. ' +
|
||||||
|
'This is necessary because DLL injection is often detected as a virus, but is necessary to modify Fortnite. ' +
|
||||||
|
'This option was designed for advanced users who want to manually manage the exclusions list on their machine. ' +
|
||||||
|
'If you do not trust the Reboot Launcher, you can audit the source code at https://github.com/Auties00/reboot_launcher and build it from source.',
|
||||||
|
False,
|
||||||
|
False
|
||||||
|
);
|
||||||
|
Page.Add('&Add the launcher to the Windows Exclusions list');
|
||||||
|
Page.Values[0] := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ShouldSkipPage(PageID: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
var
|
||||||
|
ResultCode: Integer;
|
||||||
|
InstallationDir: String;
|
||||||
|
begin
|
||||||
|
if (CurStep = ssPostInstall) and Page.Values[0] then
|
||||||
|
begin
|
||||||
|
InstallationDir := ExpandConstant('{app}');
|
||||||
|
Exec('powershell.exe', '-ExecutionPolicy Bypass -Command ""Add-MpPreference -ExclusionPath ''' + InstallationDir + '''""' , '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||||
|
Log('Powershell exit code: ' + IntToStr(ResultCode));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function CompareVersion(version1, version2: String): Integer;
|
function CompareVersion(version1, version2: String): Integer;
|
||||||
var
|
var
|
||||||
packVersion1, packVersion2: Int64;
|
packVersion1, packVersion2: Int64;
|
||||||
|
|||||||
Reference in New Issue
Block a user