diff --git a/lib/src/page/home_page.dart b/lib/src/page/home_page.dart index 8f78302..299cd5c 100644 --- a/lib/src/page/home_page.dart +++ b/lib/src/page/home_page.dart @@ -1,8 +1,6 @@ -import 'dart:ui'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:get_storage/get_storage.dart'; import 'package:reboot_launcher/src/page/info_page.dart'; import 'package:reboot_launcher/src/page/launcher_page.dart'; @@ -12,9 +10,7 @@ import 'package:reboot_launcher/src/widget/window_border.dart'; import 'package:window_manager/window_manager.dart'; import 'package:reboot_launcher/src/util/os.dart'; -import 'package:get/get.dart'; -import '../controller/build_controller.dart'; import '../util/reboot.dart'; class HomePage extends StatefulWidget { diff --git a/lib/src/page/info_page.dart b/lib/src/page/info_page.dart index 1d79417..edfe6e2 100644 --- a/lib/src/page/info_page.dart +++ b/lib/src/page/info_page.dart @@ -31,7 +31,7 @@ class InfoPage extends StatelessWidget { ), const Expanded( child: Align( - alignment: Alignment.bottomLeft, child: Text("Version 3.7${kDebugMode ? '-DEBUG' : ''}"))) + alignment: Alignment.bottomLeft, child: Text("Version 3.8${kDebugMode ? '-DEBUG' : ''}"))) ], ); } diff --git a/lib/src/util/os.dart b/lib/src/util/os.dart index 048240d..db08852 100644 --- a/lib/src/util/os.dart +++ b/lib/src/util/os.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:flutter_desktop_folder_picker/flutter_desktop_folder_picker.dart'; +import 'package:file_picker/file_picker.dart'; import 'package:path/path.dart' as path; File errorFile = File("${Platform.environment["Temp"]}/error.txt"); @@ -19,7 +19,7 @@ bool get isWin11 { } Future openFilePicker(String title) async => - FlutterDesktopFolderPicker.openFolderPickerDialog(title: title); + await FilePicker.platform.getDirectoryPath(dialogTitle: title); Future> scanInstallations(String input) => Directory(input) .list(recursive: true) diff --git a/lib/src/util/server.dart b/lib/src/util/server.dart index 293fc83..7a4829c 100644 --- a/lib/src/util/server.dart +++ b/lib/src/util/server.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:archive/archive_io.dart'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; +import 'package:get/get.dart'; import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; import 'package:process_run/shell.dart'; @@ -46,22 +47,29 @@ Future isLawinPortFree() async { return !process.outText.contains(" LISTENING "); // Goofy way, best we got } -void checkAddress(BuildContext context, String host, String port) { - showDialog( +Future showRemoteServerCheck(BuildContext context, String host, String port, [bool autoClose = false]) async { + var future = _pingServer(host, port).then((value) { + if(value && autoClose){ + Navigator.of(context).pop(); + } + + return value; + }); + await showDialog( context: context, builder: (context) => ContentDialog( content: FutureBuilder( - future: _pingAddress(host, port), + future: future, builder: (context, snapshot) { if(snapshot.hasData){ return SizedBox( width: double.infinity, - child: Text(snapshot.data! ? "Valid address" : "Invalid address" , textAlign: TextAlign.center) + child: Text(snapshot.data! ? "The server answered correctly" : "The remote server doesn't work correctly or the IP and/or the port are incorrect" , textAlign: TextAlign.center) ); } return const InfoLabel( - label: "Checking address...", + label: "Pinging remote lawin server...", child: SizedBox( width: double.infinity, child: ProgressBar() @@ -81,16 +89,25 @@ void checkAddress(BuildContext context, String host, String port) { ], ) ); + + return await future; } -Future _pingAddress(String host, String port) async { - var process = await Process.run( - "powershell", - ["Test-NetConnection", "-computername", host, "-port", port] - ); - - return process.exitCode == 0 - && process.outText.contains("TcpTestSucceeded : True"); +Future _pingServer(String host, String port, [bool https=false]) async { + try{ + var uri = Uri( + scheme: https ? "https" : "http", + host: host, + port: int.parse(port) + ); + var client = HttpClient() + ..connectionTimeout = const Duration(seconds: 5); + var request = await client.getUrl(uri); + var response = await request.close(); + return response.statusCode == 200; + }catch(_){ + return https ? false : await _pingServer(host, port, true); + } } Future changeEmbeddedServerState(BuildContext context, bool running) async { diff --git a/lib/src/widget/launch_button.dart b/lib/src/widget/launch_button.dart index 246e3e4..2c9c447 100644 --- a/lib/src/widget/launch_button.dart +++ b/lib/src/widget/launch_button.dart @@ -26,6 +26,7 @@ class LaunchButton extends StatefulWidget { class _LaunchButtonState extends State { final GameController _gameController = Get.find(); final ServerController _serverController = Get.find(); + bool _lawinFail = false; @override Widget build(BuildContext context) { @@ -64,12 +65,16 @@ class _LaunchButtonState extends State { return; } - _updateServerState(true); - if (!_serverController.started.value && _serverController.embedded.value && await isLawinPortFree()) { + if (_serverController.embedded.value && !_serverController.started.value && await isLawinPortFree()) { + if(!mounted){ + return; + } + var result = await changeEmbeddedServerState(context, false); _serverController.started(result); } + _updateServerState(true); _onStart(); } @@ -96,6 +101,13 @@ class _LaunchButtonState extends State { Win32Process(_gameController.eacProcess!.pid).suspend(); } + if(!_serverController.embedded.value){ + var available = await _showPingWarning(); + if(!available) { + return; + } + } + if(hosting){ await patchExe(version.executable!); } @@ -106,7 +118,7 @@ class _LaunchButtonState extends State { await _injectOrShowError("cranium.dll"); if(hosting){ - _showServerLaunchingWarning(); + await _showServerLaunchingWarning(); } } catch (exception) { _closeDialogIfOpen(); @@ -115,6 +127,10 @@ class _LaunchButtonState extends State { } void _onEnd() { + if(_lawinFail){ + return; + } + _closeDialogIfOpen(); _onStop(); } @@ -125,16 +141,62 @@ class _LaunchButtonState extends State { } var route = ModalRoute.of(context); - if(route != null && !route.isCurrent){ - Navigator.of(context).pop(false); + if(route == null || route.isCurrent){ + return; } + + Navigator.of(context).pop(false); } - void _showServerLaunchingWarning() async { + Future _showPingWarning() async { + if(!mounted){ + return false; + } + + return await showRemoteServerCheck( + context, + _serverController.host.text, + _serverController.port.text, + true + ); + } + + Future _showBrokenServerWarning() async { + if(!mounted){ + return; + } + + showDialog( + context: context, + builder: (context) => ContentDialog( + content: const SizedBox( + width: double.infinity, + child: Text("The lawin server is not working correctly", textAlign: TextAlign.center) + ), + actions: [ + SizedBox( + width: double.infinity, + child: FilledButton( + onPressed: () => Navigator.of(context).pop(), + style: ButtonStyle( + backgroundColor: ButtonState.all(Colors.red)), + child: const Text('Close'), + ) + ) + ], + ) + ); + } + + Future _showServerLaunchingWarning() async { + if(!mounted){ + return; + } + var result = await showDialog( context: context, builder: (context) => ContentDialog( - content: const InfoLabel( + content: const InfoLabel( label: "Launching reboot server...", child: SizedBox( width: double.infinity, @@ -171,8 +233,16 @@ class _LaunchButtonState extends State { return; } + if(line.contains("port 3551 failed: Connection refused")){ + _lawinFail = true; + _closeDialogIfOpen(); + _showBrokenServerWarning(); + return; + } + if (line.contains("Game Engine Initialized") && !_gameController.host.value) { _injectOrShowError("console.dll"); + return; } if(line.contains("added to UI Party led ") && _gameController.host.value){ diff --git a/lib/src/widget/server_button.dart b/lib/src/widget/server_button.dart index 93d8a47..545a084 100644 --- a/lib/src/widget/server_button.dart +++ b/lib/src/widget/server_button.dart @@ -27,7 +27,7 @@ class ServerButton extends StatelessWidget { ? !_serverController.started.value ? "Start" : "Stop" - : "Check address")), + : "Ping Server")), )), ), ); @@ -35,7 +35,7 @@ class ServerButton extends StatelessWidget { void _onPressed(BuildContext context) async { if (!_serverController.embedded.value) { - checkAddress( + showRemoteServerCheck( context, _serverController.host.text, _serverController.port.text); return; } diff --git a/pubspec.yaml b/pubspec.yaml index acbcbe5..b371955 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: reboot_launcher description: Launcher for project reboot -version: "3.7.0" +version: "3.8.0" publish_to: 'none' @@ -11,14 +11,14 @@ dependencies: flutter: sdk: flutter - bitsdojo_window: ^0.1.2 - bitsdojo_window_windows: ^0.1.2 + bitsdojo_window: ^0.1.5 + bitsdojo_window_windows: ^0.1.5 fluent_ui: ^3.12.0 system_theme: ^2.0.0 http: ^0.13.5 html: ^0.15.0 shared_preferences: ^2.0.15 - flutter_desktop_folder_picker: ^0.0.1 + file_picker: ^5.2.0+1 context_menus: ^1.0.1 process_run: ^0.12.3+2 url_launcher: ^6.1.5 @@ -31,6 +31,9 @@ dependencies: get_storage: ^2.0.3 window_manager: ^0.2.7 +dependency_overrides: + win32: ^3.0.0 + dev_dependencies: flutter_test: sdk: flutter @@ -49,9 +52,9 @@ msix_config: display_name: Reboot Launcher publisher_display_name: Auties00 identity_name: 31868Auties00.RebootLauncher - msix_version: 3.7.0.0 + msix_version: 3.8.0.0 publisher: CN=E6CD08C6-DECF-4034-A3EB-2D5FA2CA8029 logo_path: ./assets/icons/reboot.ico architecture: x64 store: true - capabilities: "internetClient" + capabilities: "internetClient" \ No newline at end of file diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 5a284e1..731d46f 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,7 +7,6 @@ #include "generated_plugin_registrant.h" #include -#include #include #include #include @@ -16,8 +15,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { BitsdojoWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); - FlutterDesktopFolderPickerPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterDesktopFolderPickerPlugin")); ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); SystemThemePluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index a327bb1..7993f64 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_windows - flutter_desktop_folder_picker screen_retriever system_theme url_launcher_windows diff --git a/windows/packaging/exe/make_config.yaml b/windows/packaging/exe/make_config.yaml new file mode 100644 index 0000000..69687f3 --- /dev/null +++ b/windows/packaging/exe/make_config.yaml @@ -0,0 +1,6 @@ +app_id: 31868Auties00.RebootLauncher +publisher_name: Auties00 +display_name: Reboot Launcher +create_desktop_icon: true +locales: + - en \ No newline at end of file