diff --git a/lib/cli.dart b/lib/cli.dart index 0ef1a6c..6a6e9f3 100644 --- a/lib/cli.dart +++ b/lib/cli.dart @@ -20,6 +20,7 @@ import 'package:win32/win32.dart'; import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:http/http.dart' as http; +// Needed because binaries can't be loaded in any other way const String _craniumDownload = "https://cdn.discordapp.com/attachments/1001161930599317524/1027684488718860309/cranium.dll"; const String _consoleDownload = "https://cdn.discordapp.com/attachments/1001161930599317524/1027684489184432188/console.dll"; const String _injectorDownload = "https://cdn.discordapp.com/attachments/1001161930599317524/1027686593697435799/injector.exe"; @@ -74,20 +75,23 @@ Future _getWindowsPath(String folderID) { Future handleCLI(List args) async { stdout.writeln("Reboot Launcher CLI Tool"); stdout.writeln("Wrote by Auties00"); - stdout.writeln("Version 3.10"); + stdout.writeln("Version 3.11"); - var gameJson = await _getControllerJson("game1"); - var serverJson = await _getControllerJson("server1"); + var gameJson = await _getControllerJson("game"); + var serverJson = await _getControllerJson("server"); + var settingsJson = await _getControllerJson("settings"); var versions = _getVersions(gameJson); var parser = ArgParser() - ..addCommand("list")..addCommand("launch") + ..addCommand("list") + ..addCommand("launch") ..addOption("version", defaultsTo: gameJson["version"]) ..addOption("username") ..addOption("server-type", allowed: ["embedded", "remote"], defaultsTo: serverJson["embedded"] ?? true ? "embedded" : "remote") ..addOption("server-host", defaultsTo: serverJson["host"]) ..addOption("server-port", defaultsTo: serverJson["port"]) + ..addOption("dll", defaultsTo: settingsJson["reboot"] ?? await loadBinary("reboot.dll", true)) ..addOption("type", allowed: ["client", "server", "headless_server"], defaultsTo: _getDefaultType(gameJson)) - ..addFlag("update", defaultsTo: true, negatable: true) + ..addFlag("update", defaultsTo: settingsJson["auto_update"] ?? true, negatable: true) ..addFlag("log", defaultsTo: false); var result = parser.parse(args); if (result.command?.name == "list") { @@ -104,7 +108,7 @@ Future handleCLI(List args) async { var dummyVersion = _createVersion(gameJson["version"], result["version"], versions); await _updateDLLs(); if(result["update"]) { - stdout.writeln("Updating DLL..."); + stdout.writeln("Updating reboot dll..."); await downloadRebootDll(0); } @@ -121,7 +125,7 @@ Future handleCLI(List args) async { return; } - await _startGameProcess(dummyVersion, type != GameType.client, result); + await _startGameProcess(dummyVersion, result["dll"], type != GameType.client, result); await _injectOrShowError("cranium.dll"); } @@ -193,7 +197,7 @@ List _getVersions(Map gameJson) { .toList(); } -Future _startGameProcess(FortniteVersion dummyVersion, bool host, ArgResults result) async { +Future _startGameProcess(FortniteVersion dummyVersion, String rebootDll, bool host, ArgResults result) async { var gamePath = dummyVersion.executable?.path; if (gamePath == null) { throw Exception("${dummyVersion.location @@ -209,7 +213,7 @@ Future _startGameProcess(FortniteVersion dummyVersion, bool host, ArgResul var verbose = result["log"]; _gameProcess = await Process.start(gamePath, createRebootArgs(username, result["type"] == "headless_server")) ..exitCode.then((_) => _onClose()) - ..outLines.forEach((line) => _onGameOutput(line, host, verbose)); + ..outLines.forEach((line) => _onGameOutput(line, rebootDll, host, verbose)); } void _onClose() { @@ -323,7 +327,7 @@ FortniteVersion _createVersion(String? versionName, String? versionPath, List _injectOrShowError(String binary) async { +Future _injectOrShowError(String binary, [bool locate = true]) async { if (_gameProcess == null) { return; } try { stdout.writeln("Injecting $binary..."); - var dll = await loadBinary(binary, true); + var dll = locate ? await loadBinary(binary, true) : File(binary); + if(!dll.existsSync()){ + throw Exception("Cannot inject $dll: missing file"); + } + var success = await injectDll(_gameProcess!.pid, dll.path, true); if (success) { return; diff --git a/lib/main.dart b/lib/main.dart index 468ff74..5da556d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,7 @@ import 'package:reboot_launcher/cli.dart'; import 'package:reboot_launcher/src/controller/build_controller.dart'; import 'package:reboot_launcher/src/controller/game_controller.dart'; import 'package:reboot_launcher/src/controller/server_controller.dart'; +import 'package:reboot_launcher/src/controller/settings_controller.dart'; import 'package:reboot_launcher/src/page/home_page.dart'; import 'package:reboot_launcher/src/util/binary.dart'; import 'package:reboot_launcher/src/util/os.dart'; @@ -28,9 +29,11 @@ void main(List args) async { await GetStorage.init("game"); await GetStorage.init("server"); await GetStorage.init("update"); + await GetStorage.init("settings"); Get.put(GameController()); Get.put(ServerController()); Get.put(BuildController()); + Get.put(SettingsController()); doWhenWindowReady(() { const size = Size(600, 365); var window = appWindow as WinDesktopWindow; @@ -52,6 +55,8 @@ class RebootApplication extends StatefulWidget { } class _RebootApplicationState extends State { + final SettingsController _settingsController = Get.find(); + @override Widget build(BuildContext context) { final color = SystemTheme.accentColor.accent.toAccentColor(); @@ -60,23 +65,20 @@ class _RebootApplicationState extends State { themeMode: ThemeMode.system, debugShowCheckedModeBanner: false, color: color, - darkTheme: ThemeData( - brightness: Brightness.dark, - accentColor: color, - visualDensity: VisualDensity.standard, - focusTheme: FocusThemeData( - glowFactor: is10footScreen() ? 2.0 : 0.0, - ), - ), - theme: ThemeData( - brightness: Brightness.light, - accentColor: color, - visualDensity: VisualDensity.standard, - focusTheme: FocusThemeData( - glowFactor: is10footScreen() ? 2.0 : 0.0, - ), - ), + darkTheme: _createTheme(Brightness.dark), + theme: _createTheme(Brightness.light), home: const HomePage(), ); } + + ThemeData _createTheme(Brightness brightness) { + return ThemeData( + brightness: brightness, + accentColor: SystemTheme.accentColor.accent.toAccentColor(), + visualDensity: VisualDensity.standard, + focusTheme: FocusThemeData( + glowFactor: is10footScreen() ? 2.0 : 0.0, + ), + ); + } } diff --git a/lib/src/controller/game_controller.dart b/lib/src/controller/game_controller.dart index 3eb8ccb..38f9bb4 100644 --- a/lib/src/controller/game_controller.dart +++ b/lib/src/controller/game_controller.dart @@ -43,9 +43,7 @@ class GameController extends GetxController { }); username = TextEditingController(text: _storage.read("${type.value == GameType.client ? 'game' : 'host'}_username") ?? ""); - username.addListener(() async { - await _storage.write("${type.value == GameType.client ? 'game' : 'host'}_username", username.text); - }); + username.addListener(() => _storage.write("${type.value == GameType.client ? 'game' : 'host'}_username", username.text)); started = RxBool(false); } diff --git a/lib/src/controller/settings_controller.dart b/lib/src/controller/settings_controller.dart new file mode 100644 index 0000000..adc29c8 --- /dev/null +++ b/lib/src/controller/settings_controller.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:reboot_launcher/src/model/fortnite_version.dart'; +import 'package:reboot_launcher/src/model/game_type.dart'; +import 'package:reboot_launcher/src/util/binary.dart'; +import 'package:system_theme/system_theme.dart'; + +class SettingsController extends GetxController { + late final GetStorage _storage; + late final String originalDll; + late final TextEditingController rebootDll; + late final TextEditingController consoleDll; + late final TextEditingController craniumDll; + late final RxBool autoUpdate; + + SettingsController() { + _storage = GetStorage("settings"); + rebootDll = _createController("reboot", "reboot.dll"); + consoleDll = _createController("console", "console.dll"); + craniumDll = _createController("cranium", "cranium.dll"); + autoUpdate = RxBool(_storage.read("auto_update") ?? true); + autoUpdate.listen((value) => _storage.write("auto_update", value)); + } + + TextEditingController _createController(String key, String name) { + var controller = TextEditingController(text: _storage.read(key) ?? "$safeBinariesDirectory\\$name"); + controller.addListener(() { + if(controller.text.isEmpty || !File(controller.text).existsSync()) { + return; + } + + _storage.write(key, controller.text); + }); + + return controller; + } +} diff --git a/lib/src/page/home_page.dart b/lib/src/page/home_page.dart index f8d9cd5..b01e6c3 100644 --- a/lib/src/page/home_page.dart +++ b/lib/src/page/home_page.dart @@ -1,6 +1,6 @@ import 'package:fluent_ui/fluent_ui.dart'; -import 'package:reboot_launcher/src/page/info_page.dart'; +import 'package:reboot_launcher/src/page/settings_page.dart'; import 'package:reboot_launcher/src/page/launcher_page.dart'; import 'package:reboot_launcher/src/page/server_page.dart'; import 'package:reboot_launcher/src/util/os.dart'; @@ -54,7 +54,7 @@ class _HomePageState extends State with WindowListener { items: [ _createPane("Home", FluentIcons.game), _createPane("Lawin", FluentIcons.server_enviroment), - _createPane("Info", FluentIcons.info), + _createPane("Settings", FluentIcons.settings) ], trailing: WindowTitleBar(focused: _focused)), content: NavigationBody( @@ -62,7 +62,7 @@ class _HomePageState extends State with WindowListener { children: [ const LauncherPage(), ServerPage(), - const InfoPage() + SettingsPage() ] ) ), diff --git a/lib/src/page/info_page.dart b/lib/src/page/info_page.dart deleted file mode 100644 index 794b0a6..0000000 --- a/lib/src/page/info_page.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:fluent_ui/fluent_ui.dart'; -import 'package:flutter/foundation.dart'; -import 'package:url_launcher/url_launcher.dart'; - -const String _discordLink = "https://discord.gg/NJU4QjxSMF"; - -class InfoPage extends StatelessWidget { - const InfoPage({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - const Expanded(child: SizedBox()), - Column( - children: [ - const CircleAvatar( - radius: 48, - backgroundImage: AssetImage("assets/images/auties.png")), - const SizedBox( - height: 16.0, - ), - const Text("Made by Auties00"), - const SizedBox( - height: 16.0, - ), - Button( - child: const Text("Join the discord"), - onPressed: () => launchUrl(Uri.parse(_discordLink))), - ], - ), - const Expanded( - child: Align( - alignment: Alignment.bottomLeft, child: Text("Version 3.10${kDebugMode ? '-DEBUG' : ''}"))) - ], - ); - } -} diff --git a/lib/src/page/launcher_page.dart b/lib/src/page/launcher_page.dart index 44a24f6..ce0d897 100644 --- a/lib/src/page/launcher_page.dart +++ b/lib/src/page/launcher_page.dart @@ -13,6 +13,7 @@ import 'package:reboot_launcher/src/widget/username_box.dart'; import 'package:reboot_launcher/src/widget/version_selector.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../controller/settings_controller.dart'; import '../util/binary.dart'; import '../util/reboot.dart'; import '../widget/warning_info.dart'; @@ -29,10 +30,11 @@ class LauncherPage extends StatefulWidget { class _LauncherPageState extends State { final GameController _gameController = Get.find(); final BuildController _buildController = Get.find(); + final SettingsController _settingsController = Get.find(); @override void initState() { - if(_gameController.updater == null) { + if(_gameController.updater == null && _settingsController.autoUpdate.value){ _gameController.updater = compute(downloadRebootDll, _updateTime) ..then((value) => _updateTime = value) ..onError(_saveError); diff --git a/lib/src/page/settings_page.dart b/lib/src/page/settings_page.dart new file mode 100644 index 0000000..eead20f --- /dev/null +++ b/lib/src/page/settings_page.dart @@ -0,0 +1,86 @@ +import 'dart:io'; + +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter/foundation.dart'; +import 'package:get/get.dart'; +import 'package:reboot_launcher/src/controller/settings_controller.dart'; +import 'package:reboot_launcher/src/widget/file_selector.dart'; +import 'package:reboot_launcher/src/widget/smart_switch.dart'; + +class SettingsPage extends StatelessWidget { + final SettingsController _settingsController = Get.find(); + + SettingsPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Form( + autovalidateMode: AutovalidateMode.always, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FileSelector( + label: "Reboot DLL", + placeholder: "Type the path to the reboot dll", + controller: _settingsController.rebootDll, + windowTitle: "Select a dll", + folder: false, + extension: "dll", + validator: _checkDll + ), + + FileSelector( + label: "Console DLL", + placeholder: "Type the path to the console dll", + controller: _settingsController.consoleDll, + windowTitle: "Select a dll", + folder: false, + extension: "dll", + validator: _checkDll + ), + + FileSelector( + label: "Cranium DLL", + placeholder: "Type the path to the cranium dll", + controller: _settingsController.craniumDll, + windowTitle: "Select a dll", + folder: false, + extension: "dll", + validator: _checkDll + ), + + SmartSwitch( + value: _settingsController.autoUpdate, + label: "Update DLLs" + ), + ], + ) + ), + + const Align( + alignment: Alignment.bottomRight, + child: Text("Version 3.11${kDebugMode ? '-DEBUG' : ''}") + ) + ], + ); + } + + String? _checkDll(String? text) { + if (text == null || text.isEmpty) { + return "Empty dll path"; + } + + if (!File(text).existsSync()) { + return "This dll doesn't exist"; + } + + if (!text.endsWith(".dll")) { + return "This file is not a dll"; + } + + return null; + } +} diff --git a/lib/src/util/binary.dart b/lib/src/util/binary.dart index 768c3be..665dd51 100644 --- a/lib/src/util/binary.dart +++ b/lib/src/util/binary.dart @@ -1,7 +1,7 @@ import 'dart:io'; Future loadBinary(String binary, bool safe) async{ - var safeBinary = File("$safeBinariesDirectory/$binary"); + var safeBinary = File("$safeBinariesDirectory\\$binary"); if(await safeBinary.exists()){ return safeBinary; } diff --git a/lib/src/util/os.dart b/lib/src/util/os.dart index 2fc55e0..a587f26 100644 --- a/lib/src/util/os.dart +++ b/lib/src/util/os.dart @@ -16,9 +16,22 @@ bool get isWin11 { return intBuild != null && intBuild > 22000; } -Future openFilePicker(String title) async => +Future openFolderPicker(String title) async => await FilePicker.platform.getDirectoryPath(dialogTitle: title); +Future openFilePicker(String extension) async { + var result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowMultiple: false, + allowedExtensions: [extension] + ); + if(result == null || result.files.isEmpty){ + return null; + } + + return result.files.first.path; +} + Future> scanInstallations(String input) => Directory(input) .list(recursive: true) .handleError((_) {}, test: (e) => e is FileSystemException) diff --git a/lib/src/widget/add_local_version.dart b/lib/src/widget/add_local_version.dart index c3edc9c..2a3076a 100644 --- a/lib/src/widget/add_local_version.dart +++ b/lib/src/widget/add_local_version.dart @@ -4,7 +4,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:get/get.dart'; import 'package:reboot_launcher/src/controller/game_controller.dart'; import 'package:reboot_launcher/src/model/fortnite_version.dart'; -import 'package:reboot_launcher/src/widget/select_file.dart'; +import 'package:reboot_launcher/src/widget/file_selector.dart'; class AddLocalVersion extends StatelessWidget { final GameController _gameController = Get.find(); @@ -76,12 +76,14 @@ class AddLocalVersion extends StatelessWidget { }, ), - SelectFile( + FileSelector( label: "Location", placeholder: "Type the game folder", windowTitle: "Select game folder", controller: _gamePathController, - validator: _checkGameFolder) + validator: _checkGameFolder, + folder: true + ) ], ); } diff --git a/lib/src/widget/add_server_version.dart b/lib/src/widget/add_server_version.dart index 1ef664d..86bcd3c 100644 --- a/lib/src/widget/add_server_version.dart +++ b/lib/src/widget/add_server_version.dart @@ -10,7 +10,7 @@ import 'package:reboot_launcher/src/controller/game_controller.dart'; import 'package:reboot_launcher/src/model/fortnite_version.dart'; import 'package:reboot_launcher/src/util/binary.dart'; import 'package:reboot_launcher/src/util/build.dart'; -import 'package:reboot_launcher/src/widget/select_file.dart'; +import 'package:reboot_launcher/src/widget/file_selector.dart'; import 'package:reboot_launcher/src/widget/version_name_input.dart'; import 'build_selector.dart'; @@ -242,12 +242,13 @@ class _AddServerVersionState extends State { VersionNameInput(controller: _nameController), - SelectFile( + FileSelector( label: "Destination", placeholder: "Type the download destination", windowTitle: "Select download destination", controller: _pathController, - validator: _checkDownloadDestination + validator: _checkDownloadDestination, + folder: true ), ], ); diff --git a/lib/src/widget/select_file.dart b/lib/src/widget/file_selector.dart similarity index 70% rename from lib/src/widget/select_file.dart rename to lib/src/widget/file_selector.dart index 5fdc80e..a100622 100644 --- a/lib/src/widget/select_file.dart +++ b/lib/src/widget/file_selector.dart @@ -3,29 +3,34 @@ import 'package:flutter/foundation.dart'; import '../util/os.dart'; -class SelectFile extends StatefulWidget { +class FileSelector extends StatefulWidget { final String label; final String placeholder; final String windowTitle; final bool allowNavigator; final TextEditingController controller; final String? Function(String?) validator; + final String? extension; + final bool folder; - const SelectFile( + const FileSelector( {required this.label, required this.placeholder, required this.windowTitle, required this.controller, required this.validator, + required this.folder, + this.extension, this.allowNavigator = true, Key? key}) - : super(key: key); + : assert(folder || extension != null, "Missing extension for file selector"), + super(key: key); @override - State createState() => _SelectFileState(); + State createState() => _FileSelectorState(); } -class _SelectFileState extends State { +class _FileSelectorState extends State { bool _selecting = false; @override @@ -47,7 +52,7 @@ class _SelectFileState extends State { Padding( padding: const EdgeInsets.only(bottom: 21.0), child: Tooltip( - message: "Select a folder", + message: "Select a ${widget.folder ? 'folder' : 'file'}", child: Button( onPressed: _onPressed, child: const Icon(FluentIcons.open_folder_horizontal) @@ -66,7 +71,14 @@ class _SelectFileState extends State { } _selecting = true; - compute(openFilePicker, "Select the game folder") + if(widget.folder) { + compute(openFolderPicker, widget.windowTitle) + .then((value) => widget.controller.text = value ?? "") + .then((_) => _selecting = false); + return; + } + + compute(openFilePicker, widget.extension!) .then((value) => widget.controller.text = value ?? "") .then((_) => _selecting = false); } diff --git a/lib/src/widget/launch_button.dart b/lib/src/widget/launch_button.dart index 7cc776a..36f9553 100644 --- a/lib/src/widget/launch_button.dart +++ b/lib/src/widget/launch_button.dart @@ -15,6 +15,7 @@ import 'package:reboot_launcher/src/util/server.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:win32_suspend_process/win32_suspend_process.dart'; +import '../controller/settings_controller.dart'; import '../util/server_standalone.dart'; class LaunchButton extends StatefulWidget { @@ -29,6 +30,7 @@ class LaunchButton extends StatefulWidget { class _LaunchButtonState extends State { final GameController _gameController = Get.find(); final ServerController _serverController = Get.find(); + final SettingsController _settingsController = Get.find(); File? _logFile; bool _fail = false; @@ -114,7 +116,7 @@ class _LaunchButtonState extends State { _gameController.gameProcess = await Process.start(gamePath, createRebootArgs(_gameController.username.text, hosting)) ..exitCode.then((_) => _onEnd()) ..outLines.forEach(_onGameOutput); - await _injectOrShowError("cranium.dll"); + await _injectOrShowError(Injectable.cranium); if(hosting){ await _showServerLaunchingWarning(); @@ -333,12 +335,12 @@ class _LaunchButtonState extends State { } if (line.contains("Game Engine Initialized") && _gameController.type.value == GameType.client) { - _injectOrShowError("console.dll"); + _injectOrShowError(Injectable.console); return; } if(line.contains("Region") && _gameController.type.value != GameType.client){ - _injectOrShowError("reboot.dll") + _injectOrShowError(Injectable.reboot) .then((value) => _closeDialogIfOpen(true)); } } @@ -374,22 +376,33 @@ class _LaunchButtonState extends State { _gameController.kill(); } - Future _injectOrShowError(String binary) async { + Future _injectOrShowError(Injectable injectable) async { var gameProcess = _gameController.gameProcess; if (gameProcess == null) { return; } try { - var dll = await loadBinary(binary, true); - var success = await injectDll(gameProcess.pid, dll.path); + var dllPath = _getDllPath(injectable); + var success = await injectDll(gameProcess.pid, dllPath); if (success) { return; } - _onInjectError(binary); + _onInjectError(injectable.name); } catch (exception) { - _onInjectError(binary); + _onInjectError(injectable.name); + } + } + + String _getDllPath(Injectable injectable){ + switch(injectable){ + case Injectable.reboot: + return _settingsController.rebootDll.text; + case Injectable.console: + return _settingsController.consoleDll.text; + case Injectable.cranium: + return _settingsController.craniumDll.text; } } @@ -398,3 +411,9 @@ class _LaunchButtonState extends State { launchUrl(injectLogFile.uri); } } + +enum Injectable { + console, + cranium, + reboot +} diff --git a/lib/src/widget/scan_local_version.dart b/lib/src/widget/scan_local_version.dart index bced423..e4680fb 100644 --- a/lib/src/widget/scan_local_version.dart +++ b/lib/src/widget/scan_local_version.dart @@ -4,7 +4,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:path/path.dart' as path; import 'package:reboot_launcher/src/util/os.dart'; -import 'package:reboot_launcher/src/widget/select_file.dart'; +import 'package:reboot_launcher/src/widget/file_selector.dart'; class ScanLocalVersion extends StatefulWidget { @@ -83,12 +83,14 @@ class _ScanLocalVersionState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SelectFile( + FileSelector( label: "Location", placeholder: "Type the folder to scan", windowTitle: "Select the folder to scan", controller: _folderController, - validator: _checkScanFolder) + validator: _checkScanFolder, + folder: true + ) ], ); } diff --git a/lib/src/widget/smart_input.dart b/lib/src/widget/smart_input.dart index cbba0dd..db469dc 100644 --- a/lib/src/widget/smart_input.dart +++ b/lib/src/widget/smart_input.dart @@ -1,7 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; class SmartInput extends StatelessWidget { - final String label; + final String? label; final String placeholder; final TextEditingController controller; final TextInputType type; @@ -11,13 +11,13 @@ class SmartInput extends StatelessWidget { const SmartInput( {Key? key, - required this.label, - required this.placeholder, - required this.controller, - this.onTap, - this.enabled = true, - this.populate = false, - this.type = TextInputType.text}) + required this.placeholder, + required this.controller, + this.label, + this.onTap, + this.enabled = true, + this.populate = false, + this.type = TextInputType.text}) : super(key: key); @override diff --git a/pubspec.yaml b/pubspec.yaml index c12a291..bd14a44 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: reboot_launcher description: Launcher for project reboot -version: "3.10.0" +version: "3.11.0" publish_to: 'none' @@ -56,7 +56,7 @@ msix_config: display_name: Reboot Launcher publisher_display_name: Auties00 identity_name: 31868Auties00.RebootLauncher - msix_version: 3.10.0.0 + msix_version: 3.11.0.0 publisher: CN=E6CD08C6-DECF-4034-A3EB-2D5FA2CA8029 logo_path: ./assets/icons/reboot.ico architecture: x64