From d5e41ed64674afd1ffbe05f877d8abc27260dca3 Mon Sep 17 00:00:00 2001 From: Alessandro Autiero Date: Mon, 30 Dec 2024 19:13:08 +0100 Subject: [PATCH] 10.0.5 --- archive/move.py | 2 +- archive/versions.txt | 2 +- common/lib/src/model/dll.dart | 7 +- common/lib/src/util/backend.dart | 2 +- common/lib/src/util/dll.dart | 33 +- gui/lib/main.dart | 17 +- .../src/controller/backend_controller.dart | 380 ++++++++++++++++-- gui/lib/src/controller/dll_controller.dart | 104 +++-- .../src/controller/settings_controller.dart | 2 +- .../src/messenger/{abstract => }/dialog.dart | 2 +- .../src/messenger/implementation/server.dart | 323 --------------- .../messenger/{abstract => }/info_bar.dart | 0 .../src/messenger/{abstract => }/overlay.dart | 4 +- gui/lib/src/page/{abstract => }/page.dart | 4 +- .../page/{abstract => }/page_suggestion.dart | 0 .../src/page/{abstract => }/page_type.dart | 0 gui/lib/src/page/pages.dart | 20 +- .../src/widget/{ => file}/file_selector.dart | 0 .../widget/{ => file}/file_setting_tile.dart | 4 +- .../src/widget/{ => fluent}/profile_tile.dart | 6 +- .../src/widget/{ => fluent}/setting_tile.dart | 20 +- .../widget/{ => game}/game_start_button.dart | 14 +- .../message}/data.dart | 2 +- .../message}/dll.dart | 2 +- .../message}/error.dart | 2 +- .../message}/onboard.dart | 16 +- .../message}/profile.dart | 3 +- .../message}/version.dart | 4 +- .../page}/backend_page.dart | 16 +- .../page}/browser_page.dart | 24 +- .../page}/home_page.dart | 116 ++---- .../page}/host_page.dart | 20 +- .../page}/info_page.dart | 10 +- .../page}/play_page.dart | 17 +- .../page}/settings_page.dart | 30 +- .../{ => server}/server_start_button.dart | 1 - .../{ => server}/server_type_selector.dart | 4 +- gui/lib/src/widget/title_bar.dart | 51 --- gui/lib/src/widget/title_bar_buttons.dart | 174 -------- gui/lib/src/widget/title_bar_icons.dart | 118 ------ gui/lib/src/widget/title_bar_mouse.dart | 71 ---- .../{ => version}/version_selector.dart | 6 +- .../{ => version}/version_selector_tile.dart | 6 +- .../widget/{ => window}/info_bar_area.dart | 0 .../src/widget/{ => window}/info_tile.dart | 0 gui/pubspec.yaml | 11 +- .../flutter/generated_plugin_registrant.cc | 6 +- gui/windows/flutter/generated_plugins.cmake | 2 +- gui/windows/runner/win32_window.cpp | 44 +- 49 files changed, 635 insertions(+), 1067 deletions(-) rename gui/lib/src/messenger/{abstract => }/dialog.dart (99%) delete mode 100644 gui/lib/src/messenger/implementation/server.dart rename gui/lib/src/messenger/{abstract => }/info_bar.dart (100%) rename gui/lib/src/messenger/{abstract => }/overlay.dart (97%) rename gui/lib/src/page/{abstract => }/page.dart (94%) rename gui/lib/src/page/{abstract => }/page_suggestion.dart (100%) rename gui/lib/src/page/{abstract => }/page_type.dart (100%) rename gui/lib/src/widget/{ => file}/file_selector.dart (100%) rename gui/lib/src/widget/{ => file}/file_setting_tile.dart (96%) rename gui/lib/src/widget/{ => fluent}/profile_tile.dart (94%) rename gui/lib/src/widget/{ => fluent}/setting_tile.dart (91%) rename gui/lib/src/widget/{ => game}/game_start_button.dart (98%) rename gui/lib/src/{messenger/implementation => widget/message}/data.dart (90%) rename gui/lib/src/{messenger/implementation => widget/message}/dll.dart (90%) rename gui/lib/src/{messenger/implementation => widget/message}/error.dart (93%) rename gui/lib/src/{messenger/implementation => widget/message}/onboard.dart (95%) rename gui/lib/src/{messenger/implementation => widget/message}/profile.dart (96%) rename gui/lib/src/{messenger/implementation => widget/message}/version.dart (99%) rename gui/lib/src/{page/implementation => widget/page}/backend_page.dart (93%) rename gui/lib/src/{page/implementation => widget/page}/browser_page.dart (93%) rename gui/lib/src/{page/implementation => widget/page}/home_page.dart (84%) rename gui/lib/src/{page/implementation => widget/page}/host_page.dart (94%) rename gui/lib/src/{page/implementation => widget/page}/info_page.dart (88%) rename gui/lib/src/{page/implementation => widget/page}/play_page.dart (79%) rename gui/lib/src/{page/implementation => widget/page}/settings_page.dart (92%) rename gui/lib/src/widget/{ => server}/server_start_button.dart (96%) rename gui/lib/src/widget/{ => server}/server_type_selector.dart (91%) delete mode 100644 gui/lib/src/widget/title_bar.dart delete mode 100644 gui/lib/src/widget/title_bar_buttons.dart delete mode 100644 gui/lib/src/widget/title_bar_icons.dart delete mode 100644 gui/lib/src/widget/title_bar_mouse.dart rename gui/lib/src/widget/{ => version}/version_selector.dart (96%) rename gui/lib/src/widget/{ => version}/version_selector_tile.dart (78%) rename gui/lib/src/widget/{ => window}/info_bar_area.dart (100%) rename gui/lib/src/widget/{ => window}/info_tile.dart (100%) diff --git a/archive/move.py b/archive/move.py index 27d5cb3..e3caf17 100644 --- a/archive/move.py +++ b/archive/move.py @@ -58,7 +58,7 @@ def main(): for future in as_completed(futures): try: uploaded_url, uploaded_key = future.result() - print(f"Uploaded: {uploaded_url} -> s3://{bucket_name}/{uploaded_key}") + print(f"Uploaded: {uploaded_url}") except Exception as e: print(f"Error uploading: {e}") diff --git a/archive/versions.txt b/archive/versions.txt index 46770e0..f092152 100644 --- a/archive/versions.txt +++ b/archive/versions.txt @@ -82,4 +82,4 @@ https://builds.rebootfn.org/17.30.zip https://builds.rebootfn.org/17.50.zip https://builds.rebootfn.org/18.40.zip https://builds.rebootfn.org/19.10.rar -https://builds.rebootfn.org/20.40.zip" \ No newline at end of file +https://builds.rebootfn.org/20.40.zip \ No newline at end of file diff --git a/common/lib/src/model/dll.dart b/common/lib/src/model/dll.dart index 8830eee..d950879 100644 --- a/common/lib/src/model/dll.dart +++ b/common/lib/src/model/dll.dart @@ -1,9 +1,10 @@ enum InjectableDll { console, - starfall, - reboot, + auth, + gameServer, + memoryLeak } extension InjectableDllVersionAware on InjectableDll { - bool get isVersionDependent => this == InjectableDll.reboot; + bool get isVersionDependent => this == InjectableDll.gameServer; } diff --git a/common/lib/src/util/backend.dart b/common/lib/src/util/backend.dart index eb8f9c0..12d20e3 100644 --- a/common/lib/src/util/backend.dart +++ b/common/lib/src/util/backend.dart @@ -61,7 +61,7 @@ Future pingBackend(String host, int port, [bool https=false]) async { await request.close().timeout(const Duration(seconds: 10)); log("[BACKEND] Ping successful"); return uri; - }catch(error){ + }catch(error) { log("[BACKEND] Cannot ping backend: $error"); return https || declaredScheme != null || isLocalHost(host) ? null : await pingBackend(host, port, true); } diff --git a/common/lib/src/util/dll.dart b/common/lib/src/util/dll.dart index ffe6253..9a101db 100644 --- a/common/lib/src/util/dll.dart +++ b/common/lib/src/util/dll.dart @@ -5,7 +5,6 @@ import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; import 'package:reboot_common/common.dart'; -bool _watcher = false; final File rebootBeforeS20DllFile = File("${dllsDirectory.path}\\reboot.dll"); final File rebootAboveS20DllFile = File("${dllsDirectory.path}\\rebootS20.dll"); const String kRebootBelowS20DownloadUrl = @@ -20,7 +19,22 @@ Future hasRebootDllUpdate(int? lastUpdateMs, {int hours = 24, bool force = return force || !exists || (hours > 0 && lastUpdate != null && now.difference(lastUpdate).inHours > hours); } -Future downloadCriticalDll(String name, String outputPath) async { +Future downloadDependency(InjectableDll dll, String outputPath) async { + String? name; + switch(dll) { + case InjectableDll.console: + name = "console.dll"; + case InjectableDll.auth: + name = "starfall.dll"; + case InjectableDll.memoryLeak: + name = "memory.dll"; + case InjectableDll.gameServer: + name = null; + } + if(name == null) { + return; + } + final response = await http.get(Uri.parse("https://github.com/Auties00/reboot_launcher/raw/master/gui/dependencies/dlls/$name")); if(response.statusCode != 200) { throw Exception("Cannot download $name: status code ${response.statusCode}"); @@ -56,17 +70,4 @@ Future _getLastUpdate(int? lastUpdateMs) async { return lastUpdateMs != null ? DateTime.fromMillisecondsSinceEpoch(lastUpdateMs) : null; -} - -Stream watchDlls() async* { - if(_watcher) { - return; - } - - _watcher = true; - await for(final event in dllsDirectory.watch(events: FileSystemEvent.delete | FileSystemEvent.move)) { - if (event.path.endsWith(".dll")) { - yield event.path; - } - } -} +} \ No newline at end of file diff --git a/gui/lib/main.dart b/gui/lib/main.dart index 36b219d..d70f19d 100644 --- a/gui/lib/main.dart +++ b/gui/lib/main.dart @@ -15,8 +15,8 @@ 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/settings_controller.dart'; -import 'package:reboot_launcher/src/messenger/implementation/error.dart'; -import 'package:reboot_launcher/src/page/implementation/home_page.dart'; +import 'package:reboot_launcher/src/widget/message/error.dart'; +import 'package:reboot_launcher/src/widget/page/home_page.dart'; import 'package:reboot_launcher/src/util/os.dart'; import 'package:reboot_launcher/src/util/url_protocol.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; @@ -82,9 +82,7 @@ Future _startApp() async { errors.add(uncaughtError); } finally{ log("[APP] Started applications with errors: $errors"); - runApp(RebootApplication( - errors: errors, - )); + runApp(RebootApplication(errors: errors)); } } @@ -176,7 +174,7 @@ Future _initWindow() async { if(isWin11) { await Window.setEffect( effect: WindowEffect.acrylic, - color: Colors.transparent, + color: Colors.green, dark: isDarkMode ); } @@ -232,7 +230,6 @@ Future> _initStorage() async { errors.add(error); } - return errors; } @@ -254,7 +251,11 @@ class _RebootApplicationState extends State { } void _handleErrors(List errors) { - errors.where((element) => element != null).forEach((element) => onError(element!, null, false)); + for(final error in errors) { + if(error != null) { + onError(error, null, false); + } + } } @override diff --git a/gui/lib/src/controller/backend_controller.dart b/gui/lib/src/controller/backend_controller.dart index 88ae028..70166d0 100644 --- a/gui/lib/src/controller/backend_controller.dart +++ b/gui/lib/src/controller/backend_controller.dart @@ -1,13 +1,25 @@ import 'dart:async'; import 'dart:io'; -import 'package:fluent_ui/fluent_ui.dart'; +import 'package:clipboard/clipboard.dart'; +import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons; +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/main.dart'; +import 'package:reboot_launcher/src/controller/game_controller.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; +import 'package:reboot_launcher/src/page/pages.dart'; +import 'package:reboot_launcher/src/util/cryptography.dart'; import 'package:reboot_launcher/src/util/keyboard.dart'; +import 'package:reboot_launcher/src/util/matchmaker.dart'; +import 'package:reboot_launcher/src/util/translations.dart'; +import 'package:url_launcher/url_launcher.dart'; class BackendController extends GetxController { static const String storageName = "v2_backend_storage"; @@ -22,6 +34,7 @@ class BackendController extends GetxController { late final Rx consoleKey; late final RxBool started; late final RxBool detached; + late final List _infoBars; StreamSubscription? worker; int? embeddedProcessPid; HttpServer? localServer; @@ -70,38 +83,52 @@ class BackendController extends GetxController { } }); gameServerAddressFocusNode = FocusNode(); - consoleKey = Rx(_readConsoleKey()); + consoleKey = Rx(() { + final consoleKeyValue = _storage?.read("console_key"); + if(consoleKeyValue == null) { + return _kDefaultConsoleKey; + } + + final consoleKeyNumber = int.tryParse(consoleKeyValue.toString()); + if(consoleKeyNumber == null) { + return _kDefaultConsoleKey; + } + + final consoleKey = PhysicalKeyboardKey(consoleKeyNumber); + if(!consoleKey.isUnrealEngineKey) { + return _kDefaultConsoleKey; + } + + return consoleKey; + }()); _writeConsoleKey(consoleKey.value); consoleKey.listen((newValue) { _storage?.write("console_key", newValue.usbHidUsage); _writeConsoleKey(newValue); }); + _infoBars = []; } - PhysicalKeyboardKey _readConsoleKey() { - final consoleKeyValue = _storage?.read("console_key"); - if(consoleKeyValue == null) { - return _kDefaultConsoleKey; - } + Future _writeConsoleKey(PhysicalKeyboardKey keyValue) async { + final defaultInput = File("${backendDirectory.path}\\CloudStorage\\DefaultInput.ini"); + await defaultInput.parent.create(recursive: true); + await defaultInput.writeAsString("[/Script/Engine.InputSettings]\n+ConsoleKeys=Tilde\n+ConsoleKeys=${keyValue.unrealEngineName}", flush: true); + } - final consoleKeyNumber = int.tryParse(consoleKeyValue.toString()); - if(consoleKeyNumber == null) { - return _kDefaultConsoleKey; + String _readHost() { + String? value = _storage?.read("${type.value.name}_host"); + if (value != null && value.isNotEmpty) { + return value; } - final consoleKey = PhysicalKeyboardKey(consoleKeyNumber); - if(!consoleKey.isUnrealEngineKey) { - return _kDefaultConsoleKey; + if (type.value != ServerType.remote) { + return kDefaultBackendHost; } - return consoleKey; + return ""; } - Future _writeConsoleKey(PhysicalKeyboardKey keyValue) async { - final defaultInput = File("${backendDirectory.path}\\CloudStorage\\DefaultInput.ini"); - await defaultInput.parent.create(recursive: true); - await defaultInput.writeAsString("[/Script/Engine.InputSettings]\n+ConsoleKeys=Tilde\n+ConsoleKeys=${keyValue.unrealEngineName}", flush: true); - } + String _readPort() => _storage?.read("${type.value.name}_port") ?? kDefaultBackendPort.toString(); void joinLocalhost() { gameServerAddress.text = kDefaultGameServerHost; @@ -121,22 +148,44 @@ class BackendController extends GetxController { detached.value = false; } - String _readHost() { - String? value = _storage?.read("${type.value.name}_host"); - if (value != null && value.isNotEmpty) { - return value; - } - - if (type.value != ServerType.remote) { - return kDefaultBackendHost; - } + Future toggleInteractive() async { + _cancel(); + final stream = started.value ? stop() : start( + onExit: () { + _cancel(); + _showRebootInfoBar( + translations.backendProcessError, + severity: InfoBarSeverity.error + ); + }, + onError: (errorMessage) { + _cancel(); + _showRebootInfoBar( + translations.backendErrorMessage, + severity: InfoBarSeverity.error, + duration: infoBarLongDuration, + action: Button( + onPressed: () => launchUrl(launcherLogFile.uri), + child: Text(translations.openLog), + ) + ); + } + ); + final completer = Completer(); + InfoBarEntry? entry; + worker = stream.listen((event) { + entry?.close(); + entry = _handeEvent(event); + if(event.type.isError) { + completer.complete(false); + }else if(event.type.isSuccess) { + completer.complete(true); + } + }); - return ""; + return await completer.future; } - String _readPort() => - _storage?.read("${type.value.name}_port") ?? kDefaultBackendPort.toString(); - Stream start({required void Function() onExit, required void Function(String) onError}) async* { try { if(started.value) { @@ -286,14 +335,267 @@ class BackendController extends GetxController { } } - Stream toggle({required void Function() onExit, required void Function(String) onError}) async* { - if(started()) { - yield* stop(); - }else { - yield* start( - onExit: onExit, - onError: onError + void _cancel() { + worker?.cancel(); // Do not await or it will hang + _infoBars.forEach((infoBar) => infoBar.close()); + _infoBars.clear(); + } + + InfoBarEntry _handeEvent(ServerResult event) { + log("[BACKEND] Handling event: $event"); + switch (event.type) { + case ServerResultType.starting: + return _showRebootInfoBar( + translations.startingServer, + severity: InfoBarSeverity.info, + loading: true, + duration: null + ); + case ServerResultType.startSuccess: + return _showRebootInfoBar( + type.value == ServerType.local ? translations.checkedServer : translations.startedServer, + severity: InfoBarSeverity.success + ); + case ServerResultType.startError: + print(event.stackTrace); + return _showRebootInfoBar( + type.value == ServerType.local ? translations.localServerError(event.error ?? translations.unknownError) : translations.startServerError(event.error ?? translations.unknownError), + severity: InfoBarSeverity.error, + duration: infoBarLongDuration + ); + case ServerResultType.stopping: + return _showRebootInfoBar( + translations.stoppingServer, + severity: InfoBarSeverity.info, + loading: true, + duration: null + ); + case ServerResultType.stopSuccess: + return _showRebootInfoBar( + translations.stoppedServer, + severity: InfoBarSeverity.success + ); + case ServerResultType.stopError: + return _showRebootInfoBar( + translations.stopServerError(event.error ?? translations.unknownError), + severity: InfoBarSeverity.error, + duration: infoBarLongDuration + ); + case ServerResultType.missingHostError: + return _showRebootInfoBar( + translations.missingHostNameError, + severity: InfoBarSeverity.error + ); + case ServerResultType.missingPortError: + return _showRebootInfoBar( + translations.missingPortError, + severity: InfoBarSeverity.error + ); + case ServerResultType.illegalPortError: + return _showRebootInfoBar( + translations.illegalPortError, + severity: InfoBarSeverity.error + ); + case ServerResultType.freeingPort: + return _showRebootInfoBar( + translations.freeingPort, + loading: true, + duration: null + ); + case ServerResultType.freePortSuccess: + return _showRebootInfoBar( + translations.freedPort, + severity: InfoBarSeverity.success, + duration: infoBarShortDuration + ); + case ServerResultType.freePortError: + return _showRebootInfoBar( + translations.freePortError(event.error ?? translations.unknownError), + severity: InfoBarSeverity.error, + duration: infoBarLongDuration + ); + case ServerResultType.pingingRemote: + return _showRebootInfoBar( + translations.pingingServer(ServerType.remote.name), + severity: InfoBarSeverity.info, + loading: true, + duration: null + ); + case ServerResultType.pingingLocal: + return _showRebootInfoBar( + translations.pingingServer(type.value.name), + severity: InfoBarSeverity.info, + loading: true, + duration: null + ); + case ServerResultType.pingError: + return _showRebootInfoBar( + translations.pingError(type.value.name), + severity: InfoBarSeverity.error + ); + } + } + + Future joinServer(String uuid, FortniteServer server) async { + if(!kDebugMode && uuid == server.id) { + _showRebootInfoBar( + translations.joinSelfServer, + duration: infoBarLongDuration, + severity: InfoBarSeverity.error + ); + return; + } + + final version = Get.find() + .getVersionByName(server.version.toString()); + if(version == null) { + _showRebootInfoBar( + translations.cannotJoinServerVersion(server.version.toString()), + duration: infoBarLongDuration, + severity: InfoBarSeverity.error ); + return; + } + + final hashedPassword = server.password; + final hasPassword = hashedPassword != null; + final embedded = type.value == ServerType.embedded; + final author = server.author; + final encryptedIp = server.ip; + if(!hasPassword) { + final valid = await _isServerValid(encryptedIp); + if(!valid) { + return; + } + + _onServerJoined(embedded, encryptedIp, author, version); + return; + } + + final confirmPassword = await _askForPassword(); + if(confirmPassword == null) { + return; + } + + if(!checkPassword(confirmPassword, hashedPassword)) { + _showRebootInfoBar( + translations.wrongServerPassword, + duration: infoBarLongDuration, + severity: InfoBarSeverity.error + ); + return; + } + + final decryptedIp = aes256Decrypt(encryptedIp, confirmPassword); + final valid = await _isServerValid(decryptedIp); + if(!valid) { + return; + } + + _onServerJoined(embedded, decryptedIp, author, version); + } + + Future _isServerValid(String address) async { + final result = await pingGameServer(address); + if(result) { + return true; + } + + _showRebootInfoBar( + translations.offlineServer, + duration: infoBarLongDuration, + severity: InfoBarSeverity.error + ); + return false; + } + + Future _askForPassword() async { + final confirmPasswordController = TextEditingController(); + final showPassword = RxBool(false); + final showPasswordTrailing = RxBool(false); + return await showRebootDialog( + builder: (context) => FormDialog( + content: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InfoLabel( + label: translations.serverPassword, + child: Obx(() => TextFormBox( + placeholder: translations.serverPasswordPlaceholder, + controller: confirmPasswordController, + autovalidateMode: AutovalidateMode.always, + obscureText: !showPassword.value, + enableSuggestions: false, + autofocus: true, + autocorrect: false, + onChanged: (text) => showPasswordTrailing.value = text.isNotEmpty, + suffix: !showPasswordTrailing.value ? null : Button( + onPressed: () => showPassword.value = !showPassword.value, + style: ButtonStyle( + shape: WidgetStateProperty.all(const CircleBorder()), + backgroundColor: WidgetStateProperty.all(Colors.transparent) + ), + child: Icon( + showPassword.value ? FluentIcons.eye_off_24_regular : FluentIcons.eye_24_regular + ), + ) + )) + ), + const SizedBox(height: 8.0) + ], + ), + buttons: [ + DialogButton( + text: translations.serverPasswordCancel, + type: ButtonType.secondary + ), + + DialogButton( + text: translations.serverPasswordConfirm, + type: ButtonType.primary, + onTap: () => Navigator.of(context).pop(confirmPasswordController.text) + ) + ] + ) + ); + } + + void _onServerJoined(bool embedded, String decryptedIp, String author, FortniteVersion version) { + if(embedded) { + gameServerAddress.text = decryptedIp; + pageIndex.value = RebootPageType.play.index; + }else { + FlutterClipboard.controlC(decryptedIp); + } + Get.find() + .selectedVersion = version; + WidgetsBinding.instance.addPostFrameCallback((_) => _showRebootInfoBar( + embedded ? translations.joinedServer(author) : translations.copiedIp, + duration: infoBarLongDuration, + severity: InfoBarSeverity.success + )); + } + + InfoBarEntry _showRebootInfoBar(dynamic text, { + InfoBarSeverity severity = InfoBarSeverity.info, + bool loading = false, + Duration? duration = infoBarShortDuration, + void Function()? onDismissed, + Widget? action + }) { + final result = showRebootInfoBar( + text, + severity: severity, + loading: loading, + duration: duration, + onDismissed: onDismissed, + action: action + ); + if(severity == InfoBarSeverity.info || severity == InfoBarSeverity.success) { + _infoBars.add(result); } + return result; } } \ No newline at end of file diff --git a/gui/lib/src/controller/dll_controller.dart b/gui/lib/src/controller/dll_controller.dart index 9865f5b..e8017fe 100644 --- a/gui/lib/src/controller/dll_controller.dart +++ b/gui/lib/src/controller/dll_controller.dart @@ -7,9 +7,10 @@ import 'package:get_storage/get_storage.dart'; import 'package:path/path.dart'; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/main.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; import 'package:reboot_launcher/src/util/translations.dart'; import 'package:version/version.dart'; +import 'package:path/path.dart' as path; class DllController extends GetxController { static const String storageName = "v2_dll_storage"; @@ -19,6 +20,7 @@ class DllController extends GetxController { late final TextEditingController gameServerDll; late final TextEditingController unrealEngineConsoleDll; late final TextEditingController backendDll; + late final TextEditingController memoryLeakDll; late final TextEditingController gameServerPort; late final Rx timer; late final TextEditingController beforeS20Mirror; @@ -27,13 +29,13 @@ class DllController extends GetxController { late final RxnInt timestamp; late final Rx status; InfoBarEntry? infoBarEntry; - Future? _updater; DllController() { _storage = appWithNoStorage ? null : GetStorage(storageName); - gameServerDll = _createController("game_server", InjectableDll.reboot); + gameServerDll = _createController("game_server", InjectableDll.gameServer); unrealEngineConsoleDll = _createController("unreal_engine_console", InjectableDll.console); - backendDll = _createController("backend", InjectableDll.starfall); + backendDll = _createController("backend", InjectableDll.auth); + memoryLeakDll = _createController("memory_leak", InjectableDll.memoryLeak); gameServerPort = TextEditingController(text: _storage?.read("game_server_port") ?? kDefaultGameServerPort); gameServerPort.addListener(() => _storage?.write("game_server_port", gameServerPort.text)); final timerIndex = _storage?.read("timer"); @@ -57,9 +59,9 @@ class DllController extends GetxController { } void resetGame() { - gameServerDll.text = getDefaultDllPath(InjectableDll.reboot); + gameServerDll.text = getDefaultDllPath(InjectableDll.gameServer); unrealEngineConsoleDll.text = getDefaultDllPath(InjectableDll.console); - backendDll.text = getDefaultDllPath(InjectableDll.starfall); + backendDll.text = getDefaultDllPath(InjectableDll.auth); } void resetServer() { @@ -74,16 +76,6 @@ class DllController extends GetxController { } Future updateGameServerDll({bool force = false, bool silent = false}) async { - if(_updater != null) { - return await _updater!; - } - - final result = _updateGameServerDll(force, silent); - _updater = result; - return await result; - } - - Future _updateGameServerDll(bool force, bool silent) async { try { if(customGameServer.value) { status.value = UpdateStatus.success; @@ -148,15 +140,13 @@ class DllController extends GetxController { ) ); return false; - }finally { - _updater = null; } } (File, bool) getInjectableData(Version version, InjectableDll dll) { final defaultPath = canonicalize(getDefaultDllPath(dll)); switch(dll){ - case InjectableDll.reboot: + case InjectableDll.gameServer: if(customGameServer.value) { return (File(gameServerDll.text), true); } @@ -165,25 +155,47 @@ class DllController extends GetxController { case InjectableDll.console: final ue4ConsoleFile = File(unrealEngineConsoleDll.text); return (ue4ConsoleFile, canonicalize(ue4ConsoleFile.path) != defaultPath); - case InjectableDll.starfall: + case InjectableDll.auth: final backendFile = File(backendDll.text); return (backendFile, canonicalize(backendFile.path) != defaultPath); + case InjectableDll.memoryLeak: + final memoryFile = File(memoryLeakDll.text); + return (memoryFile, canonicalize(memoryFile.path) != defaultPath); + } + } + + TextEditingController getDllEditingController(InjectableDll dll) { + switch(dll) { + case InjectableDll.console: + return unrealEngineConsoleDll; + case InjectableDll.auth: + return backendDll; + case InjectableDll.gameServer: + return gameServerDll; + case InjectableDll.memoryLeak: + return memoryLeakDll; } } - String getDefaultDllPath(InjectableDll dll) => "${dllsDirectory.path}\\${dll.name}.dll"; + String getDefaultDllPath(InjectableDll dll) { + switch(dll) { + case InjectableDll.console: + return "${dllsDirectory.path}\\console.dll"; + case InjectableDll.auth: + return "${dllsDirectory.path}\\starfall.dll"; + case InjectableDll.gameServer: + return "${dllsDirectory.path}\\reboot.dll"; + case InjectableDll.memoryLeak: + return "${dllsDirectory.path}\\memory.dll"; + } + } - Future downloadCriticalDllInteractive(String filePath, {bool silent = false, bool force = false}) async { - log("[DLL] Asking for $filePath(silent: $silent)"); - final fileName = basename(filePath).toLowerCase(); - log("[DLL] File name: $fileName"); + Future download(InjectableDll dll, String filePath, {bool silent = false, bool force = false}) async { + log("[DLL] Asking for $dll at $filePath(silent: $silent, force: $force)"); InfoBarEntry? entry; try { - if (fileName.contains("reboot")) { - log("[DLL] Downloading reboot.dll..."); - return await updateGameServerDll( - silent: silent - ); + if (dll == InjectableDll.gameServer) { + return await updateGameServerDll(silent: silent); } if(!force && File(filePath).existsSync()) { @@ -199,7 +211,7 @@ class DllController extends GetxController { duration: null ); } - await downloadCriticalDll(fileName, filePath); + await downloadDependency(dll, filePath); entry?.close(); if(!silent) { entry = await showRebootInfoBar( @@ -218,13 +230,13 @@ class DllController extends GetxController { error = error.toLowerCase(); final completer = Completer(); await showRebootInfoBar( - translations.downloadDllError(error.toString(), fileName), + translations.downloadDllError(error.toString(), dll.name), duration: infoBarLongDuration, severity: InfoBarSeverity.error, onDismissed: () => completer.complete(null), action: Button( onPressed: () async { - await downloadCriticalDllInteractive(filePath); + await download(dll, filePath, silent: silent, force: force); completer.complete(null); }, child: Text(translations.downloadDllRetry), @@ -234,6 +246,32 @@ class DllController extends GetxController { return false; } } + + void guardFiles() { + for(final injectable in InjectableDll.values) { + final controller = getDllEditingController(injectable); + final defaultPath = getDefaultDllPath(injectable); + if (path.equals(controller.text, defaultPath)) { + download(injectable, controller.text); + } + controller.addListener(() async { + try { + if (!path.equals(controller.text, defaultPath)) { + return; + } + + final filePath = controller.text; + await for(final event in File(filePath).parent.watch(events: FileSystemEvent.delete | FileSystemEvent.move)) { + if (path.equals(event.path, filePath)) { + await download(injectable, filePath); + } + } + } catch(_) { + // Ignore + } + }); + } + } } extension _UpdateTimerExtension on UpdateTimer { diff --git a/gui/lib/src/controller/settings_controller.dart b/gui/lib/src/controller/settings_controller.dart index 955899f..1d4ef98 100644 --- a/gui/lib/src/controller/settings_controller.dart +++ b/gui/lib/src/controller/settings_controller.dart @@ -6,7 +6,7 @@ import 'package:get_storage/get_storage.dart'; import 'package:http/http.dart' as http; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/main.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; import 'package:reboot_launcher/src/util/translations.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:version/version.dart'; diff --git a/gui/lib/src/messenger/abstract/dialog.dart b/gui/lib/src/messenger/dialog.dart similarity index 99% rename from gui/lib/src/messenger/abstract/dialog.dart rename to gui/lib/src/messenger/dialog.dart index ff7797b..2e93ff2 100644 --- a/gui/lib/src/messenger/abstract/dialog.dart +++ b/gui/lib/src/messenger/dialog.dart @@ -1,7 +1,7 @@ import 'package:clipboard/clipboard.dart'; import 'package:fluent_ui/fluent_ui.dart' as fluent show showDialog; import 'package:fluent_ui/fluent_ui.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; import 'package:reboot_launcher/src/page/pages.dart'; import 'package:reboot_launcher/src/util/translations.dart'; diff --git a/gui/lib/src/messenger/implementation/server.dart b/gui/lib/src/messenger/implementation/server.dart deleted file mode 100644 index b4286c3..0000000 --- a/gui/lib/src/messenger/implementation/server.dart +++ /dev/null @@ -1,323 +0,0 @@ -import 'dart:async'; - -import 'package:clipboard/clipboard.dart'; -import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons; -import 'package:fluentui_system_icons/fluentui_system_icons.dart'; -import 'package:flutter/foundation.dart'; -import 'package:get/get.dart'; -import 'package:reboot_common/common.dart'; -import 'package:reboot_launcher/src/controller/backend_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/info_bar.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; -import 'package:reboot_launcher/src/page/pages.dart'; -import 'package:reboot_launcher/src/util/cryptography.dart'; -import 'package:reboot_launcher/src/util/matchmaker.dart'; -import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:url_launcher/url_launcher.dart'; - -final List _infoBars = []; - -extension ServerControllerDialog on BackendController { - void cancelInteractive() { - worker?.cancel(); // Do not await or it will hang - _infoBars.forEach((infoBar) => infoBar.close()); - _infoBars.clear(); - } - - Future toggleInteractive() async { - cancelInteractive(); - final stream = toggle( - onExit: () { - cancelInteractive(); - _showRebootInfoBar( - translations.backendProcessError, - severity: InfoBarSeverity.error - ); - }, - onError: (errorMessage) { - cancelInteractive(); - _showRebootInfoBar( - translations.backendErrorMessage, - severity: InfoBarSeverity.error, - duration: infoBarLongDuration, - action: Button( - onPressed: () => launchUrl(launcherLogFile.uri), - child: Text(translations.openLog), - ) - ); - } - ); - final completer = Completer(); - InfoBarEntry? entry; - worker = stream.listen((event) { - entry?.close(); - entry = _handeEvent(event); - if(event.type.isError) { - completer.complete(false); - }else if(event.type.isSuccess) { - completer.complete(true); - } - }); - - return await completer.future; - } - - InfoBarEntry _handeEvent(ServerResult event) { - log("[BACKEND] Handling event: $event"); - switch (event.type) { - case ServerResultType.starting: - return _showRebootInfoBar( - translations.startingServer, - severity: InfoBarSeverity.info, - loading: true, - duration: null - ); - case ServerResultType.startSuccess: - return _showRebootInfoBar( - type.value == ServerType.local ? translations.checkedServer : translations.startedServer, - severity: InfoBarSeverity.success - ); - case ServerResultType.startError: - print(event.stackTrace); - return _showRebootInfoBar( - type.value == ServerType.local ? translations.localServerError(event.error ?? translations.unknownError) : translations.startServerError(event.error ?? translations.unknownError), - severity: InfoBarSeverity.error, - duration: infoBarLongDuration - ); - case ServerResultType.stopping: - return _showRebootInfoBar( - translations.stoppingServer, - severity: InfoBarSeverity.info, - loading: true, - duration: null - ); - case ServerResultType.stopSuccess: - return _showRebootInfoBar( - translations.stoppedServer, - severity: InfoBarSeverity.success - ); - case ServerResultType.stopError: - return _showRebootInfoBar( - translations.stopServerError(event.error ?? translations.unknownError), - severity: InfoBarSeverity.error, - duration: infoBarLongDuration - ); - case ServerResultType.missingHostError: - return _showRebootInfoBar( - translations.missingHostNameError, - severity: InfoBarSeverity.error - ); - case ServerResultType.missingPortError: - return _showRebootInfoBar( - translations.missingPortError, - severity: InfoBarSeverity.error - ); - case ServerResultType.illegalPortError: - return _showRebootInfoBar( - translations.illegalPortError, - severity: InfoBarSeverity.error - ); - case ServerResultType.freeingPort: - return _showRebootInfoBar( - translations.freeingPort, - loading: true, - duration: null - ); - case ServerResultType.freePortSuccess: - return _showRebootInfoBar( - translations.freedPort, - severity: InfoBarSeverity.success, - duration: infoBarShortDuration - ); - case ServerResultType.freePortError: - return _showRebootInfoBar( - translations.freePortError(event.error ?? translations.unknownError), - severity: InfoBarSeverity.error, - duration: infoBarLongDuration - ); - case ServerResultType.pingingRemote: - return _showRebootInfoBar( - translations.pingingServer(ServerType.remote.name), - severity: InfoBarSeverity.info, - loading: true, - duration: null - ); - case ServerResultType.pingingLocal: - return _showRebootInfoBar( - translations.pingingServer(type.value.name), - severity: InfoBarSeverity.info, - loading: true, - duration: null - ); - case ServerResultType.pingError: - return _showRebootInfoBar( - translations.pingError(type.value.name), - severity: InfoBarSeverity.error - ); - } - } - - Future joinServerInteractive(String uuid, FortniteServer server) async { - if(!kDebugMode && uuid == server.id) { - _showRebootInfoBar( - translations.joinSelfServer, - duration: infoBarLongDuration, - severity: InfoBarSeverity.error - ); - return; - } - - final gameController = Get.find(); - final version = gameController.getVersionByName(server.version.toString()); - if(version == null) { - _showRebootInfoBar( - translations.cannotJoinServerVersion(server.version.toString()), - duration: infoBarLongDuration, - severity: InfoBarSeverity.error - ); - return; - } - - final hashedPassword = server.password; - final hasPassword = hashedPassword != null; - final embedded = type.value == ServerType.embedded; - final author = server.author; - final encryptedIp = server.ip; - if(!hasPassword) { - final valid = await _isServerValid(encryptedIp); - if(!valid) { - return; - } - - _onSuccess(gameController, embedded, encryptedIp, author, version); - return; - } - - final confirmPassword = await _askForPassword(); - if(confirmPassword == null) { - return; - } - - if(!checkPassword(confirmPassword, hashedPassword)) { - _showRebootInfoBar( - translations.wrongServerPassword, - duration: infoBarLongDuration, - severity: InfoBarSeverity.error - ); - return; - } - - final decryptedIp = aes256Decrypt(encryptedIp, confirmPassword); - final valid = await _isServerValid(decryptedIp); - if(!valid) { - return; - } - - _onSuccess(gameController, embedded, decryptedIp, author, version); - } - - Future _isServerValid(String address) async { - final result = await pingGameServer(address); - if(result) { - return true; - } - - _showRebootInfoBar( - translations.offlineServer, - duration: infoBarLongDuration, - severity: InfoBarSeverity.error - ); - return false; - } - - Future _askForPassword() async { - final confirmPasswordController = TextEditingController(); - final showPassword = RxBool(false); - final showPasswordTrailing = RxBool(false); - return await showRebootDialog( - builder: (context) => FormDialog( - content: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - InfoLabel( - label: translations.serverPassword, - child: Obx(() => TextFormBox( - placeholder: translations.serverPasswordPlaceholder, - controller: confirmPasswordController, - autovalidateMode: AutovalidateMode.always, - obscureText: !showPassword.value, - enableSuggestions: false, - autofocus: true, - autocorrect: false, - onChanged: (text) => showPasswordTrailing.value = text.isNotEmpty, - suffix: !showPasswordTrailing.value ? null : Button( - onPressed: () => showPassword.value = !showPassword.value, - style: ButtonStyle( - shape: WidgetStateProperty.all(const CircleBorder()), - backgroundColor: WidgetStateProperty.all(Colors.transparent) - ), - child: Icon( - showPassword.value ? FluentIcons.eye_off_24_regular : FluentIcons.eye_24_regular - ), - ) - )) - ), - const SizedBox(height: 8.0) - ], - ), - buttons: [ - DialogButton( - text: translations.serverPasswordCancel, - type: ButtonType.secondary - ), - - DialogButton( - text: translations.serverPasswordConfirm, - type: ButtonType.primary, - onTap: () => Navigator.of(context).pop(confirmPasswordController.text) - ) - ] - ) - ); - } - - void _onSuccess(GameController controller, bool embedded, String decryptedIp, String author, FortniteVersion version) { - if(embedded) { - gameServerAddress.text = decryptedIp; - pageIndex.value = RebootPageType.play.index; - }else { - FlutterClipboard.controlC(decryptedIp); - } - controller.selectedVersion = version; - WidgetsBinding.instance.addPostFrameCallback((_) => _showRebootInfoBar( - embedded ? translations.joinedServer(author) : translations.copiedIp, - duration: infoBarLongDuration, - severity: InfoBarSeverity.success - )); - } - - InfoBarEntry _showRebootInfoBar(dynamic text, { - InfoBarSeverity severity = InfoBarSeverity.info, - bool loading = false, - Duration? duration = infoBarShortDuration, - void Function()? onDismissed, - Widget? action - }) { - final result = showRebootInfoBar( - text, - severity: severity, - loading: loading, - duration: duration, - onDismissed: onDismissed, - action: action - ); - if(severity == InfoBarSeverity.info || severity == InfoBarSeverity.success) { - _infoBars.add(result); - } - return result; - } -} \ No newline at end of file diff --git a/gui/lib/src/messenger/abstract/info_bar.dart b/gui/lib/src/messenger/info_bar.dart similarity index 100% rename from gui/lib/src/messenger/abstract/info_bar.dart rename to gui/lib/src/messenger/info_bar.dart diff --git a/gui/lib/src/messenger/abstract/overlay.dart b/gui/lib/src/messenger/overlay.dart similarity index 97% rename from gui/lib/src/messenger/abstract/overlay.dart rename to gui/lib/src/messenger/overlay.dart index f2038b8..09326fb 100644 --- a/gui/lib/src/messenger/abstract/overlay.dart +++ b/gui/lib/src/messenger/overlay.dart @@ -1,6 +1,6 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/rendering.dart'; -import 'package:reboot_launcher/src/page/implementation/home_page.dart'; +import 'package:reboot_launcher/src/widget/page/home_page.dart'; import 'package:reboot_launcher/src/page/pages.dart'; typedef WidgetBuilder = Widget Function(BuildContext, void Function()); @@ -148,7 +148,7 @@ class _RenderAbsorbPointer extends RenderProxyBox { // 32 is the height of the title bar (need this offset as the overlay area doesn't include it) // Not an optimal solution but it works (calculating it is kind of complicated) - position = Offset(position.dx, position.dy + HomePage.kTitleBarHeight); + position = Offset(position.dx, position.dy); final exclusionPosition = exclusion.localToGlobal(Offset.zero); final exclusionSize = Rect.fromLTRB( exclusionPosition.dx, diff --git a/gui/lib/src/page/abstract/page.dart b/gui/lib/src/page/page.dart similarity index 94% rename from gui/lib/src/page/abstract/page.dart rename to gui/lib/src/page/page.dart index 59bd82f..3ff62fb 100644 --- a/gui/lib/src/page/abstract/page.dart +++ b/gui/lib/src/page/page.dart @@ -1,8 +1,8 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:get/get.dart'; import 'package:reboot_launcher/src/controller/settings_controller.dart'; -import 'package:reboot_launcher/src/messenger/implementation/onboard.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/widget/message/onboard.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/translations.dart'; abstract class RebootPage extends StatefulWidget { diff --git a/gui/lib/src/page/abstract/page_suggestion.dart b/gui/lib/src/page/page_suggestion.dart similarity index 100% rename from gui/lib/src/page/abstract/page_suggestion.dart rename to gui/lib/src/page/page_suggestion.dart diff --git a/gui/lib/src/page/abstract/page_type.dart b/gui/lib/src/page/page_type.dart similarity index 100% rename from gui/lib/src/page/abstract/page_type.dart rename to gui/lib/src/page/page_type.dart diff --git a/gui/lib/src/page/pages.dart b/gui/lib/src/page/pages.dart index 802376e..199e726 100644 --- a/gui/lib/src/page/pages.dart +++ b/gui/lib/src/page/pages.dart @@ -3,16 +3,16 @@ import 'dart:collection'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:get/get.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; -import 'package:reboot_launcher/src/page/implementation/backend_page.dart'; -import 'package:reboot_launcher/src/page/implementation/browser_page.dart'; -import 'package:reboot_launcher/src/page/implementation/host_page.dart'; -import 'package:reboot_launcher/src/page/implementation/info_page.dart'; -import 'package:reboot_launcher/src/page/implementation/play_page.dart'; -import 'package:reboot_launcher/src/page/implementation/settings_page.dart'; -import 'package:reboot_launcher/src/widget/info_bar_area.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; +import 'package:reboot_launcher/src/widget/page/backend_page.dart'; +import 'package:reboot_launcher/src/widget/page/browser_page.dart'; +import 'package:reboot_launcher/src/widget/page/host_page.dart'; +import 'package:reboot_launcher/src/widget/page/info_page.dart'; +import 'package:reboot_launcher/src/widget/page/play_page.dart'; +import 'package:reboot_launcher/src/widget/page/settings_page.dart'; +import 'package:reboot_launcher/src/widget/window/info_bar_area.dart'; final StreamController pagesController = StreamController.broadcast(); bool hitBack = false; diff --git a/gui/lib/src/widget/file_selector.dart b/gui/lib/src/widget/file/file_selector.dart similarity index 100% rename from gui/lib/src/widget/file_selector.dart rename to gui/lib/src/widget/file/file_selector.dart diff --git a/gui/lib/src/widget/file_setting_tile.dart b/gui/lib/src/widget/file/file_setting_tile.dart similarity index 96% rename from gui/lib/src/widget/file_setting_tile.dart rename to gui/lib/src/widget/file/file_setting_tile.dart index 4591ec4..5a36757 100644 --- a/gui/lib/src/widget/file_setting_tile.dart +++ b/gui/lib/src/widget/file/file_setting_tile.dart @@ -7,8 +7,8 @@ import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:reboot_launcher/src/util/os.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/file_selector.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/file/file_selector.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; const double _kButtonDimensions = 30; const double _kButtonSpacing = 8; diff --git a/gui/lib/src/widget/profile_tile.dart b/gui/lib/src/widget/fluent/profile_tile.dart similarity index 94% rename from gui/lib/src/widget/profile_tile.dart rename to gui/lib/src/widget/fluent/profile_tile.dart index 6d0b881..3a0df72 100644 --- a/gui/lib/src/widget/profile_tile.dart +++ b/gui/lib/src/widget/fluent/profile_tile.dart @@ -3,9 +3,9 @@ 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:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/messenger/implementation/profile.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/widget/message/profile.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/page/pages.dart'; class ProfileWidget extends StatefulWidget { diff --git a/gui/lib/src/widget/setting_tile.dart b/gui/lib/src/widget/fluent/setting_tile.dart similarity index 91% rename from gui/lib/src/widget/setting_tile.dart rename to gui/lib/src/widget/fluent/setting_tile.dart index 9b938a0..2d961cf 100644 --- a/gui/lib/src/widget/setting_tile.dart +++ b/gui/lib/src/widget/fluent/setting_tile.dart @@ -1,6 +1,6 @@ import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; import 'package:reboot_launcher/src/page/pages.dart'; import 'package:skeletons/skeletons.dart'; @@ -80,15 +80,19 @@ class SettingTileState extends State { ) else widget.icon, + const SizedBox(width: 16.0), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - widget.title == null ? _skeletonTitle : widget.title!, - widget.subtitle == null ? _skeletonSubtitle : widget.subtitle!, - ], + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + widget.title == null ? _skeletonTitle : widget.title!, + widget.subtitle == null ? _skeletonSubtitle : widget.subtitle!, + ], + ), ), - const Spacer(), + _trailing ], ), diff --git a/gui/lib/src/widget/game_start_button.dart b/gui/lib/src/widget/game/game_start_button.dart similarity index 98% rename from gui/lib/src/widget/game_start_button.dart rename to gui/lib/src/widget/game/game_start_button.dart index 5ebe0e9..c7da027 100644 --- a/gui/lib/src/widget/game_start_button.dart +++ b/gui/lib/src/widget/game/game_start_button.dart @@ -12,9 +12,8 @@ import 'package:reboot_launcher/src/controller/backend_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/messenger/abstract/dialog.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; -import 'package:reboot_launcher/src/messenger/implementation/server.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; import 'package:reboot_launcher/src/page/pages.dart'; import 'package:reboot_launcher/src/util/matchmaker.dart'; import 'package:reboot_launcher/src/util/os.dart'; @@ -242,7 +241,7 @@ class _LaunchButtonState extends State { }else{ _gameController.instance.value = instance; } - await _injectOrShowError(InjectableDll.starfall, host); + await _injectOrShowError(InjectableDll.auth, host); log("[${host ? 'HOST' : 'GAME'}] Finished creating game instance"); return instance; } @@ -398,6 +397,7 @@ class _LaunchButtonState extends State { if(instance != null && !instance.launched) { instance.launched = true; instance.tokenError = false; + await _injectOrShowError(InjectableDll.memoryLeak, host); if(!host){ await _injectOrShowError(InjectableDll.console, host); _onGameClientInjected(); @@ -406,7 +406,7 @@ class _LaunchButtonState extends State { if(gameServerPort != null) { await killProcessByPort(gameServerPort); } - await _injectOrShowError(InjectableDll.reboot, host); + await _injectOrShowError(InjectableDll.gameServer, host); _onGameServerInjected(); } } @@ -524,7 +524,7 @@ class _LaunchButtonState extends State { } await _operation?.cancel(); _operation = null; - _backendController.cancelInteractive(); + _backendController.stop(); } host = host ?? widget.host; @@ -712,7 +712,7 @@ class _LaunchButtonState extends State { } log("[${host ? 'HOST' : 'GAME'}] Path does not exist, downloading critical dll again..."); - await _dllController.downloadCriticalDllInteractive(file.path, force: true); + await _dllController.download(injectable, file.path, force: true); log("[${host ? 'HOST' : 'GAME'}] Downloaded dll again, retrying check..."); return _getDllFileOrStop(version, injectable, host, true); } diff --git a/gui/lib/src/messenger/implementation/data.dart b/gui/lib/src/widget/message/data.dart similarity index 90% rename from gui/lib/src/messenger/implementation/data.dart rename to gui/lib/src/widget/message/data.dart index d4ffab3..8b1ba5e 100644 --- a/gui/lib/src/messenger/implementation/data.dart +++ b/gui/lib/src/widget/message/data.dart @@ -1,5 +1,5 @@ import 'package:fluent_ui/fluent_ui.dart'; -import 'package:reboot_launcher/src/messenger/abstract/dialog.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; import 'package:reboot_launcher/src/util/translations.dart'; Future showResetDialog(Function() onConfirm) => showRebootDialog( diff --git a/gui/lib/src/messenger/implementation/dll.dart b/gui/lib/src/widget/message/dll.dart similarity index 90% rename from gui/lib/src/messenger/implementation/dll.dart rename to gui/lib/src/widget/message/dll.dart index 00b2bd8..18a3b89 100644 --- a/gui/lib/src/messenger/implementation/dll.dart +++ b/gui/lib/src/widget/message/dll.dart @@ -1,5 +1,5 @@ import 'package:fluent_ui/fluent_ui.dart'; -import 'package:reboot_launcher/src/messenger/abstract/dialog.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; import 'package:reboot_launcher/src/util/translations.dart'; Future showDllDeletedDialog(Function() onConfirm) => showRebootDialog( diff --git a/gui/lib/src/messenger/implementation/error.dart b/gui/lib/src/widget/message/error.dart similarity index 93% rename from gui/lib/src/messenger/implementation/error.dart rename to gui/lib/src/widget/message/error.dart index 7d9bad9..12c2b01 100644 --- a/gui/lib/src/messenger/implementation/error.dart +++ b/gui/lib/src/widget/message/error.dart @@ -1,6 +1,6 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:reboot_common/common.dart'; -import 'package:reboot_launcher/src/messenger/abstract/dialog.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; import 'package:reboot_launcher/src/page/pages.dart'; import 'package:reboot_launcher/src/util/translations.dart'; diff --git a/gui/lib/src/messenger/implementation/onboard.dart b/gui/lib/src/widget/message/onboard.dart similarity index 95% rename from gui/lib/src/messenger/implementation/onboard.dart rename to gui/lib/src/widget/message/onboard.dart index aee3536..93460c4 100644 --- a/gui/lib/src/messenger/implementation/onboard.dart +++ b/gui/lib/src/widget/message/onboard.dart @@ -5,16 +5,16 @@ import 'package:reboot_launcher/src/controller/backend_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/settings_controller.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/messenger/implementation/profile.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; -import 'package:reboot_launcher/src/page/implementation/backend_page.dart'; -import 'package:reboot_launcher/src/page/implementation/home_page.dart'; -import 'package:reboot_launcher/src/page/implementation/host_page.dart'; -import 'package:reboot_launcher/src/page/implementation/play_page.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/widget/message/profile.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; +import 'package:reboot_launcher/src/widget/page/backend_page.dart'; +import 'package:reboot_launcher/src/widget/page/home_page.dart'; +import 'package:reboot_launcher/src/widget/page/host_page.dart'; +import 'package:reboot_launcher/src/widget/page/play_page.dart'; import 'package:reboot_launcher/src/page/pages.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/version_selector.dart'; +import 'package:reboot_launcher/src/widget/version/version_selector.dart'; void startOnboarding() { final gameController = Get.find(); diff --git a/gui/lib/src/messenger/implementation/profile.dart b/gui/lib/src/widget/message/profile.dart similarity index 96% rename from gui/lib/src/messenger/implementation/profile.dart rename to gui/lib/src/widget/message/profile.dart index d9ce207..1d54082 100644 --- a/gui/lib/src/messenger/implementation/profile.dart +++ b/gui/lib/src/widget/message/profile.dart @@ -2,8 +2,7 @@ import 'package:email_validator/email_validator.dart'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/material.dart' show Icons; import 'package:get/get.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/dialog.dart'; import 'package:reboot_launcher/src/util/translations.dart'; Future showProfileForm(BuildContext context, TextEditingController username, TextEditingController password) async{ diff --git a/gui/lib/src/messenger/implementation/version.dart b/gui/lib/src/widget/message/version.dart similarity index 99% rename from gui/lib/src/messenger/implementation/version.dart rename to gui/lib/src/widget/message/version.dart index 7c480da..26334e0 100644 --- a/gui/lib/src/messenger/implementation/version.dart +++ b/gui/lib/src/widget/message/version.dart @@ -7,11 +7,11 @@ import 'package:flutter/foundation.dart'; 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/messenger/abstract/dialog.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; import 'package:reboot_launcher/src/util/os.dart'; import 'package:reboot_launcher/src/util/translations.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/file_selector.dart'; import 'package:windows_taskbar/windows_taskbar.dart'; class AddVersionDialog extends StatefulWidget { diff --git a/gui/lib/src/page/implementation/backend_page.dart b/gui/lib/src/widget/page/backend_page.dart similarity index 93% rename from gui/lib/src/page/implementation/backend_page.dart rename to gui/lib/src/widget/page/backend_page.dart index 79955a2..f661fdf 100644 --- a/gui/lib/src/page/implementation/backend_page.dart +++ b/gui/lib/src/widget/page/backend_page.dart @@ -5,16 +5,16 @@ import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/src/controller/backend_controller.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/messenger/implementation/data.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/widget/message/data.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/keyboard.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/server_start_button.dart'; -import 'package:reboot_launcher/src/widget/server_type_selector.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/server/server_start_button.dart'; +import 'package:reboot_launcher/src/widget/server/server_type_selector.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; import 'package:url_launcher/url_launcher.dart'; final GlobalKey backendTypeOverlayTargetKey = GlobalKey(); diff --git a/gui/lib/src/page/implementation/browser_page.dart b/gui/lib/src/widget/page/browser_page.dart similarity index 93% rename from gui/lib/src/page/implementation/browser_page.dart rename to gui/lib/src/widget/page/browser_page.dart index febc280..ab6c72f 100644 --- a/gui/lib/src/page/implementation/browser_page.dart +++ b/gui/lib/src/widget/page/browser_page.dart @@ -1,4 +1,3 @@ - import 'dart:async'; import 'package:fluent_ui/fluent_ui.dart'; @@ -9,12 +8,11 @@ import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/src/controller/backend_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/messenger/abstract/dialog.dart'; -import 'package:reboot_launcher/src/messenger/implementation/server.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; class BrowsePage extends RebootPage { const BrowsePage({Key? key}) : super(key: key); @@ -211,10 +209,18 @@ class _BrowsePageState extends RebootPageState { icon: Icon( hasPassword ? FluentIcons.lock : FluentIcons.globe ), - title: Text("${_formatName(entry)} • ${entry.author}"), - subtitle: Text("${_formatDescription(entry)} • ${_formatVersion(entry)}"), + title: Text( + "${_formatName(entry)} • ${entry.author}", + maxLines: 1, + overflow: TextOverflow.ellipsis + ), + subtitle: Text( + "${_formatDescription(entry)} • ${_formatVersion(entry)}", + maxLines: 1, + overflow: TextOverflow.ellipsis + ), content: Button( - onPressed: () => _backendController.joinServerInteractive(_hostingController.uuid, entry), + onPressed: () => _backendController.joinServer(_hostingController.uuid, entry), child: Text(_backendController.type.value == ServerType.embedded ? translations.joinServer : translations.copyIp), ) ); diff --git a/gui/lib/src/page/implementation/home_page.dart b/gui/lib/src/widget/page/home_page.dart similarity index 84% rename from gui/lib/src/page/implementation/home_page.dart rename to gui/lib/src/widget/page/home_page.dart index 4c03c4e..4372ce1 100644 --- a/gui/lib/src/page/implementation/home_page.dart +++ b/gui/lib/src/widget/page/home_page.dart @@ -13,20 +13,18 @@ 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/settings_controller.dart'; -import 'package:reboot_launcher/src/messenger/abstract/dialog.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/messenger/implementation/dll.dart'; -import 'package:reboot_launcher/src/messenger/implementation/server.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_suggestion.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/widget/message/dll.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_suggestion.dart'; import 'package:reboot_launcher/src/page/pages.dart'; import 'package:reboot_launcher/src/util/matchmaker.dart'; import 'package:reboot_launcher/src/util/os.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/info_bar_area.dart'; -import 'package:reboot_launcher/src/widget/profile_tile.dart'; -import 'package:reboot_launcher/src/widget/title_bar.dart'; +import 'package:reboot_launcher/src/widget/window/info_bar_area.dart'; +import 'package:reboot_launcher/src/widget/fluent/profile_tile.dart'; import 'package:version/version.dart'; import 'package:window_manager/window_manager.dart'; @@ -34,7 +32,6 @@ final GlobalKey profileOverlayKey = GlobalKey(); class HomePage extends StatefulWidget { static const double kDefaultPadding = 12.0; - static const double kTitleBarHeight = 32; const HomePage({Key? key}) : super(key: key); @@ -95,7 +92,7 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA final uuid = uri.host; final server = _hostingController.findServerById(uuid); if(server != null) { - _backendController.joinServerInteractive(_hostingController.uuid, server); + _backendController.joinServer(_hostingController.uuid, server); }else { showRebootInfoBar( translations.noServerFound, @@ -136,28 +133,7 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA dllsDirectory.createSync(recursive: true); } - final dummy = Version.parse("1"); - final dummyS20 = Version.parse("20"); - for(final injectable in InjectableDll.values) { - _downloadDll(dummy, injectable); - if(injectable.isVersionDependent) { - _downloadDll(dummyS20, injectable); - } - } - - watchDlls().listen((filePath) => showDllDeletedDialog(() { - _dllController.downloadCriticalDllInteractive(filePath); - })); - } - - void _downloadDll(Version version, InjectableDll injectable) { - final (file, custom) = _dllController.getInjectableData(version, injectable); - if(!custom) { - _dllController.downloadCriticalDllInteractive( - file.path, - silent: false - ); - } + _dllController.guardFiles(); } @override @@ -288,62 +264,36 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA _focused.value = true; } - @override - void onWindowEvent(String eventName) { - if(eventName != "move") { - WidgetsBinding.instance.addPostFrameCallback((_) => log("[WINDOW] Event: $eventName ${_focused.value}")); - } - } - @override Widget build(BuildContext context) { super.build(context); _settingsController.language.value; loadTranslations(context); - return Obx(() { - return Container( + return Container( color: FluentTheme.of(context).micaBackgroundColor.withOpacity(0.93), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: HomePage.kTitleBarHeight, - child: Row( - children: [ - _backButton, - Expanded(child: _draggableArea), - WindowTitleBar(focused: _focused()) - ], - ) - ), - Expanded( - child: Navigator( - key: appNavigatorKey, - onPopPage: (page, data) => false, - pages: [ - MaterialPage( - child: Overlay( - key: appOverlayKey, - initialEntries: [ - OverlayEntry( - maintainState: true, - builder: (context) => Row( - children: [ - _buildLateralView(), - _buildBody() - ], - ) - ) - ], - ), + child: Navigator( + key: appNavigatorKey, + onPopPage: (page, data) => false, + pages: [ + MaterialPage( + child: Overlay( + key: appOverlayKey, + initialEntries: [ + OverlayEntry( + maintainState: true, + builder: (context) => Row( + children: [ + _buildLateralView(), + _buildBody() + ], + ) ) ], - ) + ), ) ], - ), - ); - }); + ) + ); } Widget _buildBody() => Expanded( @@ -604,12 +554,6 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA ) ); - GestureDetector get _draggableArea => GestureDetector( - onDoubleTap: windowManager.maximizeOrRestore, - onHorizontalDragStart: (_) => windowManager.startDragging(), - onVerticalDragStart: (_) => windowManager.startDragging() - ); - Widget get _autoSuggestBox => Padding( padding: const EdgeInsets.symmetric( horizontal: 16.0, diff --git a/gui/lib/src/page/implementation/host_page.dart b/gui/lib/src/widget/page/host_page.dart similarity index 94% rename from gui/lib/src/page/implementation/host_page.dart rename to gui/lib/src/widget/page/host_page.dart index df5962e..ca29fb9 100644 --- a/gui/lib/src/page/implementation/host_page.dart +++ b/gui/lib/src/widget/page/host_page.dart @@ -10,18 +10,16 @@ import 'package:reboot_launcher/main.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/settings_controller.dart'; -import 'package:reboot_launcher/src/messenger/abstract/dialog.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/messenger/implementation/data.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/widget/message/data.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/file_setting_tile.dart'; -import 'package:reboot_launcher/src/widget/game_start_button.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; -import 'package:reboot_launcher/src/widget/version_selector_tile.dart'; +import 'package:reboot_launcher/src/widget/game/game_start_button.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/version/version_selector_tile.dart'; final GlobalKey hostVersionOverlayTargetKey = GlobalKey(); final GlobalKey hostInfoOverlayTargetKey = GlobalKey(); diff --git a/gui/lib/src/page/implementation/info_page.dart b/gui/lib/src/widget/page/info_page.dart similarity index 88% rename from gui/lib/src/page/implementation/info_page.dart rename to gui/lib/src/widget/page/info_page.dart index 5608973..50ddfe9 100644 --- a/gui/lib/src/page/implementation/info_page.dart +++ b/gui/lib/src/widget/page/info_page.dart @@ -1,11 +1,11 @@ import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; -import 'package:reboot_launcher/src/messenger/implementation/onboard.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/widget/message/onboard.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; import 'package:url_launcher/url_launcher_string.dart'; class InfoPage extends RebootPage { @@ -29,7 +29,7 @@ class InfoPage extends RebootPage { class _InfoPageState extends RebootPageState { static const String _kReportBugUrl = "https://github.com/Auties00/reboot_launcher/issues/new"; - static const String _kDiscordInviteUrl = "https://discord.gg/reboot"; + static const String _kDiscordInviteUrl = "https://discord.gg/rebootmp"; @override List get settings => [ diff --git a/gui/lib/src/page/implementation/play_page.dart b/gui/lib/src/widget/page/play_page.dart similarity index 79% rename from gui/lib/src/page/implementation/play_page.dart rename to gui/lib/src/widget/page/play_page.dart index 4f68074..6b779b0 100644 --- a/gui/lib/src/page/implementation/play_page.dart +++ b/gui/lib/src/widget/page/play_page.dart @@ -1,15 +1,16 @@ import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:get/get.dart'; +import 'package:reboot_launcher/src/controller/dll_controller.dart'; import 'package:reboot_launcher/src/controller/game_controller.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; -import 'package:reboot_launcher/src/messenger/implementation/data.dart'; -import 'package:reboot_launcher/src/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; +import 'package:reboot_launcher/src/widget/message/data.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/game_start_button.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; -import 'package:reboot_launcher/src/widget/version_selector_tile.dart'; +import 'package:reboot_launcher/src/widget/game/game_start_button.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/version/version_selector_tile.dart'; final GlobalKey gameVersionOverlayTargetKey = GlobalKey(); @@ -34,6 +35,7 @@ class PlayPage extends RebootPage { class _PlayPageState extends RebootPageState { final GameController _gameController = Get.find(); + final DllController _dllController = Get.find(); @override Widget? get button => LaunchButton( @@ -81,6 +83,7 @@ class _PlayPageState extends RebootPageState { content: Button( onPressed: () => showResetDialog(() { _gameController.reset(); + _dllController.resetGame(); }), child: Text(translations.gameResetDefaultsContent), ) diff --git a/gui/lib/src/page/implementation/settings_page.dart b/gui/lib/src/widget/page/settings_page.dart similarity index 92% rename from gui/lib/src/page/implementation/settings_page.dart rename to gui/lib/src/widget/page/settings_page.dart index 6c14773..69d302a 100644 --- a/gui/lib/src/page/implementation/settings_page.dart +++ b/gui/lib/src/widget/page/settings_page.dart @@ -6,12 +6,12 @@ import 'package:get/get.dart'; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/src/controller/dll_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/page/abstract/page.dart'; -import 'package:reboot_launcher/src/page/abstract/page_type.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/page/page.dart'; +import 'package:reboot_launcher/src/page/page_type.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/file_setting_tile.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/file/file_setting_tile.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; import 'package:url_launcher/url_launcher.dart'; class SettingsPage extends RebootPage { @@ -62,7 +62,7 @@ class _SettingsPageState extends RebootPageState { onReset: () { final path = _dllController.getDefaultDllPath(InjectableDll.console); _dllController.unrealEngineConsoleDll.text = path; - _dllController.downloadCriticalDllInteractive(path, force: true); + _dllController.download(InjectableDll.console, path, force: true); } ), createFileSetting( @@ -70,9 +70,19 @@ class _SettingsPageState extends RebootPageState { description: translations.settingsClientAuthDescription, controller: _dllController.backendDll, onReset: () { - final path = _dllController.getDefaultDllPath(InjectableDll.starfall); + final path = _dllController.getDefaultDllPath(InjectableDll.auth); _dllController.backendDll.text = path; - _dllController.downloadCriticalDllInteractive(path, force: true); + _dllController.download(InjectableDll.auth, path, force: true); + } + ), + createFileSetting( + title: translations.settingsClientMemoryName, + description: translations.settingsClientMemoryDescription, + controller: _dllController.memoryLeakDll, + onReset: () { + final path = _dllController.getDefaultDllPath(InjectableDll.memoryLeak); + _dllController.memoryLeakDll.text = path; + _dllController.download(InjectableDll.memoryLeak, path, force: true); } ), _internalFilesServerType, @@ -176,9 +186,9 @@ class _SettingsPageState extends RebootPageState { description: translations.settingsServerFileDescription, controller: _dllController.gameServerDll, onReset: () { - final path = _dllController.getDefaultDllPath(InjectableDll.reboot); + final path = _dllController.getDefaultDllPath(InjectableDll.gameServer); _dllController.gameServerDll.text = path; - _dllController.downloadCriticalDllInteractive(path); + _dllController.download(InjectableDll.gameServer, path); } ); } diff --git a/gui/lib/src/widget/server_start_button.dart b/gui/lib/src/widget/server/server_start_button.dart similarity index 96% rename from gui/lib/src/widget/server_start_button.dart rename to gui/lib/src/widget/server/server_start_button.dart index 81da42b..9aa398b 100644 --- a/gui/lib/src/widget/server_start_button.dart +++ b/gui/lib/src/widget/server/server_start_button.dart @@ -4,7 +4,6 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:get/get.dart'; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/src/controller/backend_controller.dart'; -import 'package:reboot_launcher/src/messenger/implementation/server.dart'; import 'package:reboot_launcher/src/util/translations.dart'; class ServerButton extends StatefulWidget { diff --git a/gui/lib/src/widget/server_type_selector.dart b/gui/lib/src/widget/server/server_type_selector.dart similarity index 91% rename from gui/lib/src/widget/server_type_selector.dart rename to gui/lib/src/widget/server/server_type_selector.dart index 62854a4..82fdf8e 100644 --- a/gui/lib/src/widget/server_type_selector.dart +++ b/gui/lib/src/widget/server/server_type_selector.dart @@ -2,8 +2,8 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:get/get.dart'; import 'package:reboot_common/common.dart'; import 'package:reboot_launcher/src/controller/backend_controller.dart'; -import 'package:reboot_launcher/src/messenger/abstract/dialog.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; import 'package:reboot_launcher/src/util/translations.dart'; class ServerTypeSelector extends StatefulWidget { diff --git a/gui/lib/src/widget/title_bar.dart b/gui/lib/src/widget/title_bar.dart deleted file mode 100644 index 7b324b5..0000000 --- a/gui/lib/src/widget/title_bar.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:fluent_ui/fluent_ui.dart'; -import 'package:reboot_launcher/src/util/os.dart'; -import 'package:reboot_launcher/src/widget/title_bar_buttons.dart'; -import 'package:system_theme/system_theme.dart'; - -class WindowTitleBar extends StatelessWidget { - final bool focused; - - const WindowTitleBar({Key? key, required this.focused}) : super(key: key); - - @override - Widget build(BuildContext context) { - var lightMode = FluentTheme.of(context).brightness.isLight; - return Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - MinimizeWindowButton( - colors: WindowButtonColors( - iconNormal: focused || !isWin11 ? lightMode ? Colors.black : Colors.white : SystemTheme.accentColor.lighter, - iconMouseDown: lightMode ? Colors.black : Colors.white, - iconMouseOver: lightMode ? Colors.black : Colors.white, - normal: Colors.transparent, - mouseOver: _color, - mouseDown: _color.withOpacity(0.7)), - ), - MaximizeWindowButton( - colors: WindowButtonColors( - iconNormal: focused || !isWin11 ? lightMode ? Colors.black : Colors.white : SystemTheme.accentColor.lighter, - iconMouseDown: lightMode ? Colors.black : Colors.white, - iconMouseOver: lightMode ? Colors.black : Colors.white, - normal: Colors.transparent, - mouseOver: _color, - mouseDown: _color.withOpacity(0.7)), - ), - CloseWindowButton( - colors: WindowButtonColors( - iconNormal: focused || !isWin11 ? lightMode ? Colors.black : Colors.white : SystemTheme.accentColor.lighter, - iconMouseDown: lightMode ? Colors.black : Colors.white, - iconMouseOver: lightMode ? Colors.black : Colors.white, - normal: Colors.transparent, - mouseOver: Colors.red, - mouseDown: Colors.red.withOpacity(0.7), - ), - ), - ], - ); - } - - Color get _color => - SystemTheme.accentColor.accent; -} diff --git a/gui/lib/src/widget/title_bar_buttons.dart b/gui/lib/src/widget/title_bar_buttons.dart deleted file mode 100644 index 24eae84..0000000 --- a/gui/lib/src/widget/title_bar_buttons.dart +++ /dev/null @@ -1,174 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:reboot_launcher/src/util/os.dart'; -import 'package:window_manager/window_manager.dart'; - -import 'title_bar_icons.dart'; -import 'title_bar_mouse.dart'; - -typedef WindowButtonIconBuilder = Widget Function( - WindowButtonContext buttonContext); -typedef WindowButtonBuilder = Widget Function( - WindowButtonContext buttonContext, Widget icon); - -class WindowButtonContext { - BuildContext context; - MouseState mouseState; - Color? backgroundColor; - Color iconColor; - - WindowButtonContext( - {required this.context, - required this.mouseState, - this.backgroundColor, - required this.iconColor}); -} - -class WindowButtonColors { - late Color normal; - late Color mouseOver; - late Color mouseDown; - late Color iconNormal; - late Color iconMouseOver; - late Color iconMouseDown; - - WindowButtonColors( - {Color? normal, - Color? mouseOver, - Color? mouseDown, - Color? iconNormal, - Color? iconMouseOver, - Color? iconMouseDown}) { - this.normal = normal ?? _defaultButtonColors.normal; - this.mouseOver = mouseOver ?? _defaultButtonColors.mouseOver; - this.mouseDown = mouseDown ?? _defaultButtonColors.mouseDown; - this.iconNormal = iconNormal ?? _defaultButtonColors.iconNormal; - this.iconMouseOver = iconMouseOver ?? _defaultButtonColors.iconMouseOver; - this.iconMouseDown = iconMouseDown ?? _defaultButtonColors.iconMouseDown; - } -} - -final _defaultButtonColors = WindowButtonColors( - normal: Colors.transparent, - iconNormal: const Color(0xFF805306), - mouseOver: const Color(0xFF404040), - mouseDown: const Color(0xFF202020), - iconMouseOver: const Color(0xFFFFFFFF), - iconMouseDown: const Color(0xFFF0F0F0)); - -class WindowButton extends StatelessWidget { - final WindowButtonBuilder? builder; - final WindowButtonIconBuilder? iconBuilder; - late final WindowButtonColors colors; - final bool animate; - final EdgeInsets? padding; - final VoidCallback? onPressed; - - WindowButton( - {Key? key, - WindowButtonColors? colors, - this.builder, - @required this.iconBuilder, - this.padding, - this.onPressed, - this.animate = false}) - : super(key: key) { - this.colors = colors ?? _defaultButtonColors; - } - - Color getBackgroundColor(MouseState mouseState) { - if (mouseState.isMouseDown) return colors.mouseDown; - if (mouseState.isMouseOver) return colors.mouseOver; - return colors.normal; - } - - Color getIconColor(MouseState mouseState) { - if (mouseState.isMouseDown) return colors.iconMouseDown; - if (mouseState.isMouseOver) return colors.iconMouseOver; - return colors.iconNormal; - } - - @override - Widget build(BuildContext context) { - return MouseStateBuilder( - builder: (context, mouseState) { - WindowButtonContext buttonContext = WindowButtonContext( - mouseState: mouseState, - context: context, - backgroundColor: getBackgroundColor(mouseState), - iconColor: getIconColor(mouseState)); - - var icon = - (iconBuilder != null) ? iconBuilder!(buttonContext) : Container(); - var fadeOutColor = - getBackgroundColor(MouseState()..isMouseOver = true) - .withOpacity(0); - var padding = this.padding ?? EdgeInsets.zero; - var animationMs = mouseState.isMouseOver - ? (animate ? 100 : 0) - : (animate ? 200 : 0); - Widget iconWithPadding = Padding(padding: padding, child: icon); - iconWithPadding = AnimatedContainer( - curve: Curves.easeOut, - duration: Duration(milliseconds: animationMs), - color: buttonContext.backgroundColor ?? fadeOutColor, - child: iconWithPadding); - var button = (builder != null) - ? builder!(buttonContext, icon) - : iconWithPadding; - return SizedBox.square(dimension: 45, child: button); - }, - onPressed: onPressed); - } -} - -class MinimizeWindowButton extends WindowButton { - MinimizeWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) - : super( - key: key, - colors: colors, - animate: animate ?? false, - iconBuilder: (buttonContext) => - MinimizeIcon(color: buttonContext.iconColor), - onPressed: onPressed ?? () => windowManager.minimize()); -} - -class MaximizeWindowButton extends WindowButton { - MaximizeWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) - : super( - key: key, - colors: colors, - animate: animate ?? false, - iconBuilder: (buttonContext) => - MaximizeIcon(color: buttonContext.iconColor), - onPressed: onPressed ?? - () => windowManager.maximizeOrRestore()); -} - -final _defaultCloseButtonColors = WindowButtonColors( - mouseOver: const Color(0xFFD32F2F), - mouseDown: const Color(0xFFB71C1C), - iconNormal: const Color(0xFF805306), - iconMouseOver: const Color(0xFFFFFFFF)); - -class CloseWindowButton extends WindowButton { - CloseWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) - : super( - key: key, - colors: colors ?? _defaultCloseButtonColors, - animate: animate ?? false, - iconBuilder: (buttonContext) => - CloseIcon(color: buttonContext.iconColor), - onPressed: onPressed ?? () => windowManager.close()); -} diff --git a/gui/lib/src/widget/title_bar_icons.dart b/gui/lib/src/widget/title_bar_icons.dart deleted file mode 100644 index a2ec1fd..0000000 --- a/gui/lib/src/widget/title_bar_icons.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/widgets.dart'; - -class CloseIcon extends StatelessWidget { - final Color color; - - const CloseIcon({Key? key, required this.color}) : super(key: key); - - @override - Widget build(BuildContext context) => Align( - alignment: Alignment.topLeft, - child: Stack(children: [ - Transform.rotate( - angle: pi * .25, - child: - Center(child: Container(width: 14, height: 1, color: color))), - Transform.rotate( - angle: pi * -.25, - child: - Center(child: Container(width: 14, height: 1, color: color))), - ]), - ); -} - -class MaximizeIcon extends StatelessWidget { - final Color color; - - const MaximizeIcon({Key? key, required this.color}) : super(key: key); - - @override - Widget build(BuildContext context) => _AlignedPaint(_MaximizePainter(color)); -} - -class _MaximizePainter extends _IconPainter { - _MaximizePainter(Color color) : super(color); - - @override - void paint(Canvas canvas, Size size) { - Paint p = getPaint(color); - canvas.drawRect(Rect.fromLTRB(0, 0, size.width - 1, size.height - 1), p); - } -} - -class RestoreIcon extends StatelessWidget { - final Color color; - - const RestoreIcon({ - Key? key, - required this.color, - }) : super(key: key); - - @override - Widget build(BuildContext context) => _AlignedPaint(_RestorePainter(color)); -} - -class _RestorePainter extends _IconPainter { - _RestorePainter(Color color) : super(color); - - @override - void paint(Canvas canvas, Size size) { - Paint p = getPaint(color); - canvas.drawRect(Rect.fromLTRB(0, 2, size.width - 2, size.height), p); - canvas.drawLine(const Offset(2, 2), const Offset(2, 0), p); - canvas.drawLine(const Offset(2, 0), Offset(size.width, 0), p); - canvas.drawLine( - Offset(size.width, 0), Offset(size.width, size.height - 2), p); - canvas.drawLine(Offset(size.width, size.height - 2), - Offset(size.width - 2, size.height - 2), p); - } -} - -class MinimizeIcon extends StatelessWidget { - final Color color; - - const MinimizeIcon({Key? key, required this.color}) : super(key: key); - - @override - Widget build(BuildContext context) => _AlignedPaint(_MinimizePainter(color)); -} - -class _MinimizePainter extends _IconPainter { - _MinimizePainter(Color color) : super(color); - - @override - void paint(Canvas canvas, Size size) { - Paint p = getPaint(color); - canvas.drawLine( - Offset(0, size.height / 2), Offset(size.width, size.height / 2), p); - } -} - -abstract class _IconPainter extends CustomPainter { - _IconPainter(this.color); - - final Color color; - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) => false; -} - -class _AlignedPaint extends StatelessWidget { - const _AlignedPaint(this.painter, {Key? key}) : super(key: key); - final CustomPainter painter; - - @override - Widget build(BuildContext context) { - return Align( - alignment: Alignment.center, - child: CustomPaint(size: const Size(10, 10), painter: painter)); - } -} - -Paint getPaint(Color color, [bool isAntiAlias = false]) => Paint() - ..color = color - ..style = PaintingStyle.stroke - ..isAntiAlias = isAntiAlias - ..strokeWidth = 1; diff --git a/gui/lib/src/widget/title_bar_mouse.dart b/gui/lib/src/widget/title_bar_mouse.dart deleted file mode 100644 index 21f680d..0000000 --- a/gui/lib/src/widget/title_bar_mouse.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:flutter/widgets.dart'; - -typedef MouseStateBuilderCB = Widget Function( - BuildContext context, MouseState mouseState); - -class MouseState { - bool isMouseOver; - bool isMouseDown; - - MouseState() : isMouseOver = false, isMouseDown = false; -} - -class MouseStateBuilder extends StatefulWidget { - final MouseStateBuilderCB builder; - final VoidCallback? onPressed; - - const MouseStateBuilder({Key? key, required this.builder, this.onPressed}) - : super(key: key); - - @override - State createState() => _MouseStateBuilderState(); -} - -class _MouseStateBuilderState extends State { - late MouseState _mouseState; - - _MouseStateBuilderState() { - _mouseState = MouseState(); - } - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (event) { - setState(() { - _mouseState.isMouseOver = true; - }); - }, - onExit: (event) { - setState(() { - _mouseState.isMouseOver = false; - }); - }, - child: GestureDetector( - onTapDown: (_) { - setState(() { - _mouseState.isMouseDown = true; - }); - }, - onTapCancel: () { - setState(() { - _mouseState.isMouseDown = false; - }); - }, - onTap: () { - setState(() { - _mouseState.isMouseDown = false; - _mouseState.isMouseOver = false; - }); - WidgetsBinding.instance.addPostFrameCallback((_) { - if (widget.onPressed != null) { - widget.onPressed!(); - } - }); - }, - onTapUp: (_) {}, - child: widget.builder(context, _mouseState) - ) - ); - } -} diff --git a/gui/lib/src/widget/version_selector.dart b/gui/lib/src/widget/version/version_selector.dart similarity index 96% rename from gui/lib/src/widget/version_selector.dart rename to gui/lib/src/widget/version/version_selector.dart index 089def7..90aec27 100644 --- a/gui/lib/src/widget/version_selector.dart +++ b/gui/lib/src/widget/version/version_selector.dart @@ -6,9 +6,9 @@ import 'package:flutter/gestures.dart'; 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/messenger/abstract/dialog.dart'; -import 'package:reboot_launcher/src/messenger/abstract/info_bar.dart'; -import 'package:reboot_launcher/src/messenger/implementation/version.dart'; +import 'package:reboot_launcher/src/messenger/dialog.dart'; +import 'package:reboot_launcher/src/messenger/info_bar.dart'; +import 'package:reboot_launcher/src/widget/message/version.dart'; import 'package:reboot_launcher/src/util/translations.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/gui/lib/src/widget/version_selector_tile.dart b/gui/lib/src/widget/version/version_selector_tile.dart similarity index 78% rename from gui/lib/src/widget/version_selector_tile.dart rename to gui/lib/src/widget/version/version_selector_tile.dart index 8afa343..895789e 100644 --- a/gui/lib/src/widget/version_selector_tile.dart +++ b/gui/lib/src/widget/version/version_selector_tile.dart @@ -1,9 +1,9 @@ import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; -import 'package:reboot_launcher/src/messenger/abstract/overlay.dart'; +import 'package:reboot_launcher/src/messenger/overlay.dart'; import 'package:reboot_launcher/src/util/translations.dart'; -import 'package:reboot_launcher/src/widget/setting_tile.dart'; -import 'package:reboot_launcher/src/widget/version_selector.dart'; +import 'package:reboot_launcher/src/widget/fluent/setting_tile.dart'; +import 'package:reboot_launcher/src/widget/version/version_selector.dart'; SettingTile buildVersionSelector({ required GlobalKey key diff --git a/gui/lib/src/widget/info_bar_area.dart b/gui/lib/src/widget/window/info_bar_area.dart similarity index 100% rename from gui/lib/src/widget/info_bar_area.dart rename to gui/lib/src/widget/window/info_bar_area.dart diff --git a/gui/lib/src/widget/info_tile.dart b/gui/lib/src/widget/window/info_tile.dart similarity index 100% rename from gui/lib/src/widget/info_tile.dart rename to gui/lib/src/widget/window/info_tile.dart diff --git a/gui/pubspec.yaml b/gui/pubspec.yaml index c104749..be082f9 100644 --- a/gui/pubspec.yaml +++ b/gui/pubspec.yaml @@ -1,11 +1,15 @@ name: reboot_launcher description: Graphical User Interface for Project Reboot -version: "10.0.4" +version: "10.0.5" publish_to: 'none' environment: - sdk: ">=3.0.0 <=4.0.0" + # 3.19.0 is the last version that supports Windows 7/8/8.1 officially + # I have no clue who is still using Windows 7, but some users requested support, so might as well add it + # Repository Issue: https://github.com/Auties00/Reboot-Launcher/issues/58 + # Flutter issue: https://github.com/flutter/flutter/issues/140830#issuecomment-1936397549 + sdk: ">=3.0.0 <=3.19.0" dependencies: # The flutter SDK @@ -18,8 +22,7 @@ dependencies: # Windows UI 3 fluent_ui: ^4.9.1 - flutter_acrylic: - path: ./dependencies/flutter_acrylic + flutter_acrylic: ^1.1.4 fluentui_system_icons: ^1.1.258 system_theme: ^3.1.1 skeletons: diff --git a/gui/windows/flutter/generated_plugin_registrant.cc b/gui/windows/flutter/generated_plugin_registrant.cc index 1498af3..3fbfb5d 100644 --- a/gui/windows/flutter/generated_plugin_registrant.cc +++ b/gui/windows/flutter/generated_plugin_registrant.cc @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -22,8 +22,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FlutterAcrylicPlugin")); LocalNotifierPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("LocalNotifierPlugin")); - ScreenRetrieverPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); + ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi")); SystemThemePluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("SystemThemePlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/gui/windows/flutter/generated_plugins.cmake b/gui/windows/flutter/generated_plugins.cmake index b6a020c..6cd7442 100644 --- a/gui/windows/flutter/generated_plugins.cmake +++ b/gui/windows/flutter/generated_plugins.cmake @@ -6,7 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links flutter_acrylic local_notifier - screen_retriever + screen_retriever_windows system_theme url_launcher_windows window_manager diff --git a/gui/windows/runner/win32_window.cpp b/gui/windows/runner/win32_window.cpp index 76f3adb..e67dfcb 100644 --- a/gui/windows/runner/win32_window.cpp +++ b/gui/windows/runner/win32_window.cpp @@ -6,6 +6,10 @@ #include +#include + +#include "Windowsx.h" + namespace { constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; @@ -160,52 +164,45 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, } LRESULT -Win32Window::MessageHandler(HWND hwnd, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: +Win32Window::MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept { + switch (uMsg) { + case WM_DESTROY: { window_handle_ = nullptr; Destroy(); if (quit_on_close_) { PostQuitMessage(0); } return 0; + } case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); + auto newRectSize = reinterpret_cast(lParam); LONG newWidth = newRectSize->right - newRectSize->left; LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - + SetWindowPos(hWnd, nullptr, newRectSize->left, newRectSize->top, newWidth,newHeight, SWP_NOZORDER | SWP_NOACTIVATE); return 0; } + case WM_SIZE: { - RECT rect = GetClientArea(); + auto rect = GetClientArea(); if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top, TRUE); } - return 0; + return DefWindowProc(child_content_, uMsg, wParam, lParam); } - case WM_ACTIVATE: + case WM_ACTIVATE: { if (child_content_ != nullptr) { SetFocus(child_content_); } return 0; + } - case WM_NCCALCSIZE: - return 0; + default: + return DefWindowProc(window_handle_, uMsg, wParam, lParam); + } } - return DefWindowProc(window_handle_, message, wparam, lparam); -} - void Win32Window::Destroy() { OnDestroy(); @@ -228,8 +225,7 @@ void Win32Window::SetChildContent(HWND content) { SetParent(content, window_handle_); RECT frame = GetClientArea(); - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); + MoveWindow(content, frame.left, frame.top, frame.right - frame.left,frame.bottom - frame.top, true); SetFocus(child_content_); }