diff --git a/assets/images/auth.png b/assets/images/auth.png
new file mode 100644
index 0000000..999befe
Binary files /dev/null and b/assets/images/auth.png differ
diff --git a/assets/images/cloud.png b/assets/images/cloud.png
new file mode 100644
index 0000000..0e484f1
Binary files /dev/null and b/assets/images/cloud.png differ
diff --git a/assets/images/download.png b/assets/images/download.png
new file mode 100644
index 0000000..9b66b0d
Binary files /dev/null and b/assets/images/download.png differ
diff --git a/assets/images/host.png b/assets/images/host.png
new file mode 100644
index 0000000..573e59f
Binary files /dev/null and b/assets/images/host.png differ
diff --git a/assets/images/info.png b/assets/images/info.png
new file mode 100644
index 0000000..f6037ad
Binary files /dev/null and b/assets/images/info.png differ
diff --git a/assets/images/play.png b/assets/images/play.png
new file mode 100644
index 0000000..1e370e5
Binary files /dev/null and b/assets/images/play.png differ
diff --git a/assets/images/settings.png b/assets/images/settings.png
new file mode 100644
index 0000000..17312b6
Binary files /dev/null and b/assets/images/settings.png differ
diff --git a/assets/images/user.png b/assets/images/user.png
new file mode 100644
index 0000000..68947e0
Binary files /dev/null and b/assets/images/user.png differ
diff --git a/dependencies/bitsdojo_window-0.1.5/CHANGELOG.md b/dependencies/bitsdojo_window-0.1.5/CHANGELOG.md
deleted file mode 100644
index c022588..0000000
--- a/dependencies/bitsdojo_window-0.1.5/CHANGELOG.md
+++ /dev/null
@@ -1,45 +0,0 @@
-## 0.1.5
- - Runs on Windows 7
-## 0.1.4
- - Updated win32 to 3.0.0
-## 0.1.3
- - Updated ffi to 2.0.0
-## 0.1.2
- - Flutter 3.0 support
-## 0.1.1+1
- - Added Linux usage instructions
-## 0.1.1
- - Linux support now stable
-## 0.1.0+1
- - Fix gtk library name on Linux
-## 0.1.0
- - Added null safety support
-## 0.0.9
- - Linux support added
-## 0.0.8
- - Added macOS readme instructions
-## 0.0.7
- - macOS support added
-## 0.0.6
- - Works with latest Flutter version (master channel)
-## 0.0.5
- - Works with latest Flutter version (dev channel)
-## 0.0.4
- - Better integration with other plugins
-## 0.0.3
- - Using dpi-aware values for title bar and buttons dimensions
- - Dynamically calculating default button padding instead of fixed one
-## 0.0.2
- - Added video tutorial link
-## 0.0.1
-
-* Initial release
- - Custom window frame - remove standard Windows titlebar and buttons
- - Hide window on startup
- - Show/hide window
- - Minimize/Maximize/Restore/Close window
- - Move window using Flutter widget
- - Set window size, minimum size and maximum size
- - Set window position
- - Set window alignment on screen (center/topLeft/topRight/bottomLeft/bottomRight)
- - Set window title
diff --git a/dependencies/bitsdojo_window-0.1.5/LICENSE b/dependencies/bitsdojo_window-0.1.5/LICENSE
deleted file mode 100644
index 93d3f15..0000000
--- a/dependencies/bitsdojo_window-0.1.5/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020-2021 Bogdan Hobeanu
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dependencies/bitsdojo_window-0.1.5/README.md b/dependencies/bitsdojo_window-0.1.5/README.md
deleted file mode 100644
index a55b3e1..0000000
--- a/dependencies/bitsdojo_window-0.1.5/README.md
+++ /dev/null
@@ -1,262 +0,0 @@
-# bitsdojo_window
-
-A [Flutter package](https://pub.dev/packages/bitsdojo_window) that makes it easy to customize and work with your Flutter desktop app window **on Windows, macOS and Linux**.
-
-Watch the tutorial to get started. Click the image below to watch the video:
-
-[](https://www.youtube.com/watch?v=bee2AHQpGK4 "Click to open")
-
-
-
-**Features**:
-
- - Custom window frame - remove standard Windows/macOS/Linux titlebar and buttons
- - Hide window on startup
- - Show/hide window
- - Move window using Flutter widget
- - Minimize/Maximize/Restore/Close window
- - Set window size, minimum size and maximum size
- - Set window position
- - Set window alignment on screen (center/topLeft/topRight/bottomLeft/bottomRight)
- - Set window title
-
-# Getting Started
-
-Install the package using `pubspec.yaml`
-
-# For Windows apps
-
-Inside your application folder, go to `windows\runner\main.cpp` and add these two lines at the beginning of the file:
-
-```cpp
-#include
-auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP);
-```
-
-# For macOS apps
-
-Inside your application folder, go to `macos\runner\MainFlutterWindow.swift` and add this line after the one saying `import FlutterMacOS` :
-
-```swift
-import FlutterMacOS
-import bitsdojo_window_macos // Add this line
-```
-
-Then change this line from:
-
-```swift
-class MainFlutterWindow: NSWindow {
-```
-
-to this:
-
-```swift
-class MainFlutterWindow: BitsdojoWindow {
-```
-
-After changing `NSWindow` to `BitsdojoWindow` add these lines below the line you changed:
-
-```swift
-override func bitsdojo_window_configure() -> UInt {
- return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP
-}
-```
-
-Your code should now look like this:
-
-```swift
-class MainFlutterWindow: BitsdojoWindow {
-
- override func bitsdojo_window_configure() -> UInt {
- return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP
- }
-
- override func awakeFromNib() {
- ... //rest of your code
-```
-#
-
-If you don't want to use a custom frame and prefer the standard window titlebar and buttons, you can remove the `BDW_CUSTOM_FRAME` flag from the code above.
-
-If you don't want to hide the window on startup, you can remove the `BDW_HIDE_ON_STARTUP` flag from the code above.
-
-# For Linux apps
-
-Inside your application folder, go to `linux\my_application.cc` and add this line at the beginning of the file:
-
-```cpp
-#include
-```
-Then look for these two lines:
-
-```cpp
-gtk_window_set_default_size(window, 1280, 720);
-gtk_widget_show(GTK_WIDGET(window));
-```
-and change them to this:
-
-```cpp
-auto bdw = bitsdojo_window_from(window); // <--- add this line
-bdw->setCustomFrame(true); // <-- add this line
-//gtk_window_set_default_size(window, 1280, 720); // <-- comment this line
-gtk_widget_show(GTK_WIDGET(window));
-```
-
-As you can see, we commented the line calling `gtk_window_set_default_size` and added these two lines before `gtk_widget_show(GTK_WIDGET(window));`
-
-```cpp
-auto bdw = bitsdojo_window_from(window);
-bdw->setCustomFrame(true);
-```
-
-# Flutter app integration
-
-Now go to `lib\main.dart` and add this code in the `main` function right after `runApp(MyApp());` :
-
-```dart
-void main() {
- runApp(MyApp());
-
- // Add this code below
-
- doWhenWindowReady(() {
- const initialSize = Size(600, 450);
- appWindow.minSize = initialSize;
- appWindow.size = initialSize;
- appWindow.alignment = Alignment.center;
- appWindow.show();
- });
-}
-```
-This will set an initial size and a minimum size for your application window, center it on the screen and show it on the screen.
-
-You can find examples in the `example` folder.
-
-Here is an example that displays this window:
-
-Click to expand
-
-```dart
-import 'package:flutter/material.dart';
-import 'package:bitsdojo_window/bitsdojo_window.dart';
-
-void main() {
- runApp(const MyApp());
- doWhenWindowReady(() {
- final win = appWindow;
- const initialSize = Size(600, 450);
- win.minSize = initialSize;
- win.size = initialSize;
- win.alignment = Alignment.center;
- win.title = "Custom window with Flutter";
- win.show();
- });
-}
-
-const borderColor = Color(0xFF805306);
-
-class MyApp extends StatelessWidget {
- const MyApp({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- debugShowCheckedModeBanner: false,
- home: Scaffold(
- body: WindowBorder(
- color: borderColor,
- width: 1,
- child: Row(
- children: const [LeftSide(), RightSide()],
- ),
- ),
- ),
- );
- }
-}
-
-const sidebarColor = Color(0xFFF6A00C);
-
-class LeftSide extends StatelessWidget {
- const LeftSide({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return SizedBox(
- width: 200,
- child: Container(
- color: sidebarColor,
- child: Column(
- children: [
- WindowTitleBarBox(child: MoveWindow()),
- Expanded(child: Container())
- ],
- )));
- }
-}
-
-const backgroundStartColor = Color(0xFFFFD500);
-const backgroundEndColor = Color(0xFFF6A00C);
-
-class RightSide extends StatelessWidget {
- const RightSide({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return Expanded(
- child: Container(
- decoration: const BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- colors: [backgroundStartColor, backgroundEndColor],
- stops: [0.0, 1.0]),
- ),
- child: Column(children: [
- WindowTitleBarBox(
- child: Row(
- children: [Expanded(child: MoveWindow()), const WindowButtons()],
- ),
- )
- ]),
- ),
- );
- }
-}
-
-final buttonColors = WindowButtonColors(
- iconNormal: const Color(0xFF805306),
- mouseOver: const Color(0xFFF6A00C),
- mouseDown: const Color(0xFF805306),
- iconMouseOver: const Color(0xFF805306),
- iconMouseDown: const Color(0xFFFFD500));
-
-final closeButtonColors = WindowButtonColors(
- mouseOver: const Color(0xFFD32F2F),
- mouseDown: const Color(0xFFB71C1C),
- iconNormal: const Color(0xFF805306),
- iconMouseOver: Colors.white);
-
-class WindowButtons extends StatelessWidget {
- const WindowButtons({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return Row(
- children: [
- MinimizeWindowButton(colors: buttonColors),
- MaximizeWindowButton(colors: buttonColors),
- CloseWindowButton(colors: closeButtonColors),
- ],
- );
- }
-}
-```
-
-
-#
-# ❤️ **Sponsors - friends helping this package**
-
-I am developing this package in my spare time and any help is appreciated.
-If you want to help you can [become a sponsor](https://github.com/sponsors/bitsdojo).
-
-🙏 Thank you!
-
-Want to help? [Become a sponsor](https://github.com/sponsors/bitsdojo)
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/bitsdojo_window.dart b/dependencies/bitsdojo_window-0.1.5/lib/bitsdojo_window.dart
deleted file mode 100644
index 0b3205e..0000000
--- a/dependencies/bitsdojo_window-0.1.5/lib/bitsdojo_window.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-export 'src/widgets/window_border.dart';
-export 'src/widgets/window_button.dart';
-export 'src/widgets/window_caption.dart';
-export 'src/icons/icons.dart';
-export 'src/app_window.dart';
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/src/app_window.dart b/dependencies/bitsdojo_window-0.1.5/lib/src/app_window.dart
deleted file mode 100644
index 8ab6e38..0000000
--- a/dependencies/bitsdojo_window-0.1.5/lib/src/app_window.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-import 'package:bitsdojo_window_platform_interface/bitsdojo_window_platform_interface.dart';
-import 'package:bitsdojo_window_platform_interface/method_channel_bitsdojo_window.dart';
-import 'package:bitsdojo_window_windows/bitsdojo_window_windows.dart';
-import 'package:bitsdojo_window_macos/bitsdojo_window_macos.dart';
-import 'package:bitsdojo_window_linux/bitsdojo_window_linux.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter/foundation.dart' show kIsWeb;
-import 'dart:io' show Platform;
-
-bool _platformInstanceNeedsInit = true;
-
-void initPlatformInstance() {
- if (!kIsWeb) {
- if (BitsdojoWindowPlatform.instance is MethodChannelBitsdojoWindow) {
- if (Platform.isWindows) {
- BitsdojoWindowPlatform.instance = BitsdojoWindowWindows();
- } else if (Platform.isMacOS) {
- BitsdojoWindowPlatform.instance = BitsdojoWindowMacOS();
- } else if (Platform.isLinux) {
- BitsdojoWindowPlatform.instance = BitsdojoWindowLinux();
- }
- }
- } else {
- BitsdojoWindowPlatform.instance = BitsdojoWindowPlatformNotImplemented();
- }
-}
-
-BitsdojoWindowPlatform get _platform {
- var needsInit = _platformInstanceNeedsInit;
- if (needsInit) {
- initPlatformInstance();
- _platformInstanceNeedsInit = false;
- }
- return BitsdojoWindowPlatform.instance;
-}
-
-void doWhenWindowReady(VoidCallback callback) {
- _platform.doWhenWindowReady(callback);
-}
-
-DesktopWindow get appWindow {
- return _platform.appWindow;
-}
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_border.dart b/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_border.dart
deleted file mode 100644
index 5592653..0000000
--- a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_border.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-import 'package:bitsdojo_window_windows/bitsdojo_window_windows.dart'
- show WinDesktopWindow;
-import 'package:flutter/foundation.dart';
-import 'package:flutter/widgets.dart';
-import '../app_window.dart';
-
-class WindowBorder extends StatelessWidget {
- final Widget child;
- final Color color;
- final double? width;
-
- WindowBorder({Key? key, required this.child, required this.color, this.width})
- : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- bool isWindowsApp =
- (!kIsWeb) && (defaultTargetPlatform == TargetPlatform.windows);
- bool isLinuxApp =
- (!kIsWeb) && (defaultTargetPlatform == TargetPlatform.linux);
-
- // Only show border on Windows and Linux
- if (!(isWindowsApp || isLinuxApp)) {
- return child;
- }
-
- var borderWidth = width ?? 1;
- var topBorderWidth = width ?? 1;
-
- if (appWindow is WinDesktopWindow) {
- appWindow as WinDesktopWindow..setWindowCutOnMaximize(borderWidth.ceil());
- }
-
- if (isWindowsApp) {
- topBorderWidth += 1 / appWindow.scaleFactor;
- }
- final topBorderSide = BorderSide(color: this.color, width: topBorderWidth);
- final borderSide = BorderSide(color: this.color, width: borderWidth);
-
- return Container(
- child: child,
- decoration: BoxDecoration(
- border: Border(
- top: topBorderSide,
- left: borderSide,
- right: borderSide,
- bottom: borderSide)));
- }
-}
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_caption.dart b/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_caption.dart
deleted file mode 100644
index 2a15b59..0000000
--- a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_caption.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-import 'package:flutter/widgets.dart';
-import '../app_window.dart';
-import 'package:flutter/foundation.dart' show kIsWeb;
-
-class _MoveWindow extends StatelessWidget {
- _MoveWindow({Key? key, this.child, this.onDoubleTap}) : super(key: key);
- final Widget? child;
- final VoidCallback? onDoubleTap;
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- behavior: HitTestBehavior.translucent,
- onPanStart: (details) {
- appWindow.startDragging();
- },
- onDoubleTap: this.onDoubleTap ?? () => appWindow.maximizeOrRestore(),
- child: this.child ?? Container());
- }
-}
-
-class MoveWindow extends StatelessWidget {
- final Widget? child;
- final VoidCallback? onDoubleTap;
- MoveWindow({Key? key, this.child, this.onDoubleTap}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- if (child == null) return _MoveWindow(onDoubleTap: this.onDoubleTap);
- return _MoveWindow(
- onDoubleTap: this.onDoubleTap,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [Expanded(child: this.child!)]),
- );
- }
-}
-
-class WindowTitleBarBox extends StatelessWidget {
- final Widget? child;
- WindowTitleBarBox({Key? key, this.child}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- if (kIsWeb) {
- return Container();
- }
- final titlebarHeight = appWindow.titleBarHeight;
- return SizedBox(height: titlebarHeight, child: this.child ?? Container());
- }
-}
diff --git a/dependencies/bitsdojo_window-0.1.5/pubspec.yaml b/dependencies/bitsdojo_window-0.1.5/pubspec.yaml
deleted file mode 100644
index 47ef658..0000000
--- a/dependencies/bitsdojo_window-0.1.5/pubspec.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: bitsdojo_window
-description: A package to help with creating custom windows with Flutter desktop (custom border, titlebar and minimize/maximize/close buttons) and common desktop window operations (show/hide/position on screen) for Windows and macOS
-version: 0.1.5
-homepage: https://www.bitsdojo.com
-repository: https://github.com/bitsdojo/bitsdojo_window
-
-environment:
- sdk: ">=2.17.0 <3.0.0"
- flutter: ">=1.20.0"
-
-flutter:
- plugin:
- platforms:
- windows:
- default_package: bitsdojo_window_windows
- macos:
- default_package: bitsdojo_window_macos
- linux:
- default_package: bitsdojo_window_linux
-
-dependencies:
- flutter:
- sdk: flutter
- bitsdojo_window_platform_interface: ^0.1.2
- #path: ../bitsdojo_window_platform_interface
- bitsdojo_window_windows: ^0.1.5
- #path: ../bitsdojo_window_windows
- bitsdojo_window_macos: ^0.1.3
- #path: ../bitsdojo_window_macos
- bitsdojo_window_linux: ^0.1.3
- #path: ../bitsdojo_window_linux
diff --git a/lib/cli.dart b/lib/cli.dart
index f126fc9..58edec4 100644
--- a/lib/cli.dart
+++ b/lib/cli.dart
@@ -68,12 +68,11 @@ void main(List args) async {
}
stdout.writeln("Launching game...");
- if(version.executable == null){
+ var executable = await version.executable;
+ if(executable == null){
throw Exception("Missing game executable at: ${version.location.path}");
}
- await patchHeadless(version.executable!);
-
var serverType = getServerType(result);
var serverHost = result["server-host"] ?? serverJson["${serverType.id}_host"];
var serverPort = result["server-port"] ?? serverJson["${serverType.id}_port"];
diff --git a/lib/main.dart b/lib/main.dart
index 0188371..c7013da 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,8 +1,5 @@
import 'dart:async';
-import 'package:bitsdojo_window/bitsdojo_window.dart';
-import 'package:bitsdojo_window_windows/bitsdojo_window_windows.dart'
- show WinDesktopWindow;
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
@@ -17,6 +14,8 @@ import 'package:reboot_launcher/src/ui/page/home_page.dart';
import 'package:reboot_launcher/supabase.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:system_theme/system_theme.dart';
+import 'package:flutter_acrylic/flutter_acrylic.dart';
+import 'package:window_manager/window_manager.dart';
const double kDefaultWindowWidth = 1024;
const double kDefaultWindowHeight = 1024;
@@ -42,21 +41,21 @@ void main() async {
Get.put(BuildController());
Get.put(SettingsController());
Get.put(HostingController());
- doWhenWindowReady(() {
- var controller = Get.find();
- var size = Size(controller.width, controller.height);
- var window = appWindow as WinDesktopWindow;
- window.setWindowCutOnMaximize(appBarSize * 2);
- appWindow.size = size;
- if(controller.offsetX != null && controller.offsetY != null){
- appWindow.position = Offset(controller.offsetX!, controller.offsetY!);
- }else {
- appWindow.alignment = Alignment.center;
- }
-
- appWindow.title = "Reboot Launcher";
- appWindow.show();
- });
+ await windowManager.ensureInitialized();
+ var controller = Get.find();
+ var size = Size(controller.width, controller.height);
+ await windowManager.setSize(size);
+ if(controller.offsetX != null && controller.offsetY != null){
+ await windowManager.setPosition(Offset(controller.offsetX!, controller.offsetY!));
+ }else {
+ await windowManager.setAlignment(Alignment.center);
+ };
+ await Window.initialize();
+ await Window.setEffect(
+ effect: WindowEffect.acrylic,
+ color: Colors.transparent,
+ dark: SystemTheme.isDarkMode
+ );
var supabase = Supabase.instance.client;
await supabase.from('hosts')
.delete()
@@ -91,6 +90,7 @@ class _RebootApplicationState extends State {
FluentThemeData _createTheme(Brightness brightness) => FluentThemeData(
brightness: brightness,
accentColor: SystemTheme.accentColor.accent.toAccentColor(),
- visualDensity: VisualDensity.standard
+ visualDensity: VisualDensity.standard,
+ scaffoldBackgroundColor: Colors.transparent
);
}
diff --git a/lib/src/cli/compatibility.dart b/lib/src/cli/compatibility.dart
index bf4814b..9756966 100644
--- a/lib/src/cli/compatibility.dart
+++ b/lib/src/cli/compatibility.dart
@@ -1,8 +1,7 @@
import 'dart:collection';
import 'dart:convert';
-import 'dart:io';
-
import 'dart:ffi';
+import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';
diff --git a/lib/src/cli/config.dart b/lib/src/cli/config.dart
index b170f9e..49c8b03 100644
--- a/lib/src/cli/config.dart
+++ b/lib/src/cli/config.dart
@@ -1,9 +1,8 @@
import 'dart:convert';
import 'package:args/args.dart';
-
-import '../model/fortnite_version.dart';
-import '../model/server_type.dart';
+import 'package:reboot_launcher/src/model/fortnite_version.dart';
+import 'package:reboot_launcher/src/model/server_type.dart';
Iterable getServerTypes() => ServerType.values.map((entry) => entry.id);
diff --git a/lib/src/cli/game.dart b/lib/src/cli/game.dart
index 066560f..fea89f7 100644
--- a/lib/src/cli/game.dart
+++ b/lib/src/cli/game.dart
@@ -2,12 +2,11 @@ import 'dart:io';
import 'package:process_run/shell.dart';
import 'package:reboot_launcher/cli.dart';
-
-import '../model/fortnite_version.dart';
-import '../util/injector.dart';
-import '../util/os.dart';
-import '../util/process.dart';
-import '../util/server.dart';
+import 'package:reboot_launcher/src/model/fortnite_version.dart';
+import 'package:reboot_launcher/src/util/injector.dart';
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/util/process.dart';
+import 'package:reboot_launcher/src/util/server.dart';
final List _errorStrings = [
"port 3551 failed: Connection refused",
@@ -25,10 +24,9 @@ Future startGame() async {
await _startLauncherProcess(version);
await _startEacProcess(version);
- var gamePath = version.executable?.path;
- if (gamePath == null) {
- throw Exception("${version.location
- .path} no longer contains a Fortnite executable, did you delete or move it?");
+ var executable = await version.executable;
+ if (executable == null) {
+ throw Exception("${version.location.path} no longer contains a Fortnite executable, did you delete or move it?");
}
if (username == null) {
@@ -36,7 +34,7 @@ Future startGame() async {
stdout.writeln("No username was specified, using $username by default. Use --username to specify one");
}
- _gameProcess = await Process.start(gamePath, createRebootArgs(username!, "", host, ""))
+ _gameProcess = await Process.start(executable.path, createRebootArgs(username!, "", host, ""))
..exitCode.then((_) => _onClose())
..outLines.forEach((line) => _onGameOutput(line, dll, host, verbose));
}
diff --git a/lib/src/cli/reboot.dart b/lib/src/cli/reboot.dart
index 8994b79..b0e122d 100644
--- a/lib/src/cli/reboot.dart
+++ b/lib/src/cli/reboot.dart
@@ -1,10 +1,9 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
-import 'package:reboot_launcher/src/util/server.dart';
-
-import '../util/os.dart';
import 'package:http/http.dart' as http;
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/util/server.dart';
const String _baseDownload = "https://cdn.discordapp.com/attachments/1095351875961901057/1110968021373169674/cobalt.dll";
const String _consoleDownload = "https://cdn.discordapp.com/attachments/1095351875961901057/1110968095033524234/console.dll";
diff --git a/lib/src/cli/server.dart b/lib/src/cli/server.dart
index 49ca783..e710b58 100644
--- a/lib/src/cli/server.dart
+++ b/lib/src/cli/server.dart
@@ -1,9 +1,8 @@
import 'dart:io';
import 'package:process_run/shell.dart';
-
-import '../model/server_type.dart';
-import '../util/server.dart' as server;
+import 'package:reboot_launcher/src/model/server_type.dart';
+import 'package:reboot_launcher/src/util/server.dart' as server;
Future startServer(String? host, String? port, ServerType type) async {
stdout.writeln("Starting backend server...");
diff --git a/lib/src/model/fortnite_version.dart b/lib/src/model/fortnite_version.dart
index dab7375..61ebfde 100644
--- a/lib/src/model/fortnite_version.dart
+++ b/lib/src/model/fortnite_version.dart
@@ -1,6 +1,8 @@
import 'dart:io';
+import 'package:flutter/foundation.dart';
import 'package:path/path.dart' as path;
+import 'package:reboot_launcher/src/util/patcher.dart';
class FortniteVersion {
String name;
@@ -22,8 +24,22 @@ class FortniteVersion {
}
}
- File? get executable {
- return findExecutable(location, "FortniteClient-Win64-Shipping.exe");
+ Future get executable async {
+ var result = findExecutable(location, "FortniteClient-Win64-Shipping-Reboot.exe");
+ if(result != null) {
+ return result;
+ }
+
+ var original = findExecutable(location, "FortniteClient-Win64-Shipping.exe");
+ if(original == null) {
+ return null;
+ }
+
+ await Future.wait([
+ compute(patchMatchmaking, original),
+ compute(patchHeadless, original)
+ ]);
+ return original;
}
File? get launcher {
diff --git a/lib/src/ui/controller/game_controller.dart b/lib/src/ui/controller/game_controller.dart
index 6649dd0..3bd6862 100644
--- a/lib/src/ui/controller/game_controller.dart
+++ b/lib/src/ui/controller/game_controller.dart
@@ -1,5 +1,4 @@
import 'dart:async';
-import 'dart:collection';
import 'dart:convert';
import 'package:fluent_ui/fluent_ui.dart';
@@ -9,7 +8,6 @@ import 'package:reboot_launcher/src/model/fortnite_version.dart';
import 'package:reboot_launcher/src/model/game_instance.dart';
import 'package:uuid/uuid.dart';
-import '../../model/update_status.dart';
const String kDefaultPlayerName = "Player";
diff --git a/lib/src/ui/controller/hosting_controller.dart b/lib/src/ui/controller/hosting_controller.dart
index 6052fbd..7e37855 100644
--- a/lib/src/ui/controller/hosting_controller.dart
+++ b/lib/src/ui/controller/hosting_controller.dart
@@ -4,9 +4,9 @@ import 'package:get_storage/get_storage.dart';
import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
import 'package:reboot_launcher/src/ui/controller/update_controller.dart';
-import '../../model/game_instance.dart';
-import '../../model/update_status.dart';
-import '../../util/reboot.dart';
+import 'package:reboot_launcher/src/model/game_instance.dart';
+import 'package:reboot_launcher/src/model/update_status.dart';
+import 'package:reboot_launcher/src/util/reboot.dart';
const String kDefaultServerName = "Reboot Game Server";
diff --git a/lib/src/ui/controller/server_controller.dart b/lib/src/ui/controller/server_controller.dart
index 95e0c0a..729f43e 100644
--- a/lib/src/ui/controller/server_controller.dart
+++ b/lib/src/ui/controller/server_controller.dart
@@ -4,8 +4,8 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
-import '../../model/server_type.dart';
-import '../../util/server.dart';
+import 'package:reboot_launcher/src/model/server_type.dart';
+import 'package:reboot_launcher/src/util/server.dart';
class ServerController extends GetxController {
static const String _kDefaultServerHost = "127.0.0.1";
diff --git a/lib/src/ui/controller/settings_controller.dart b/lib/src/ui/controller/settings_controller.dart
index 2e4eb91..e10af0d 100644
--- a/lib/src/ui/controller/settings_controller.dart
+++ b/lib/src/ui/controller/settings_controller.dart
@@ -1,3 +1,4 @@
+import 'dart:ui';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
@@ -5,9 +6,8 @@ import 'package:get_storage/get_storage.dart';
import 'package:reboot_launcher/main.dart';
import 'package:reboot_launcher/src/util/os.dart';
import 'package:reboot_launcher/src/util/server.dart';
-import 'dart:ui';
-import '../../util/reboot.dart';
+import 'package:reboot_launcher/src/util/reboot.dart';
class SettingsController extends GetxController {
static const String _kDefaultIp = "127.0.0.1";
@@ -49,9 +49,9 @@ class SettingsController extends GetxController {
autoUpdate = RxBool(_storage.read("auto_update") ?? _kDefaultAutoUpdate);
autoUpdate.listen((value) => _storage.write("auto_update", value));
scrollingDistance = 0.0;
- firstRun = RxBool(_storage.read("fr") ?? true);
- firstRun.listen((value) => _storage.write("fr", value));
- index = RxInt(firstRun() ? 0 : 1);
+ firstRun = RxBool(_storage.read("first_run") ?? true);
+ firstRun.listen((value) => _storage.write("first_run", value));
+ index = RxInt(firstRun() ? 3 : 0);
}
TextEditingController _createController(String key, String name) {
diff --git a/lib/src/ui/dialog/add_local_version.dart b/lib/src/ui/dialog/add_local_version.dart
index 4f02c4e..fd1a6b5 100644
--- a/lib/src/ui/dialog/add_local_version.dart
+++ b/lib/src/ui/dialog/add_local_version.dart
@@ -6,9 +6,8 @@ import 'package:reboot_launcher/src/model/fortnite_version.dart';
import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
import 'package:reboot_launcher/src/ui/widget/home/version_name_input.dart';
-import '../../util/checks.dart';
-import '../widget/shared/file_selector.dart';
-import '../widget/shared/smart_check_box.dart';
+import 'package:reboot_launcher/src/util/checks.dart';
+import 'package:reboot_launcher/src/ui/widget/shared/file_selector.dart';
import 'dialog.dart';
import 'dialog_button.dart';
diff --git a/lib/src/ui/dialog/add_server_version.dart b/lib/src/ui/dialog/add_server_version.dart
index bde9d1d..73a6622 100644
--- a/lib/src/ui/dialog/add_server_version.dart
+++ b/lib/src/ui/dialog/add_server_version.dart
@@ -6,17 +6,16 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:reboot_launcher/src/model/fortnite_version.dart';
-import 'package:reboot_launcher/src/util/error.dart';
-import 'package:reboot_launcher/src/util/os.dart';
-import 'package:reboot_launcher/src/util/build.dart';
import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
+import 'package:reboot_launcher/src/util/build.dart';
+import 'package:reboot_launcher/src/util/os.dart';
import 'package:universal_disk_space/universal_disk_space.dart';
-import '../../util/checks.dart';
-import '../controller/build_controller.dart';
-import '../widget/home/build_selector.dart';
-import '../widget/home/version_name_input.dart';
-import '../widget/shared/file_selector.dart';
+import 'package:reboot_launcher/src/util/checks.dart';
+import 'package:reboot_launcher/src/ui/controller/build_controller.dart';
+import 'package:reboot_launcher/src/ui/widget/home/build_selector.dart';
+import 'package:reboot_launcher/src/ui/widget/home/version_name_input.dart';
+import 'package:reboot_launcher/src/ui/widget/shared/file_selector.dart';
import 'dialog.dart';
import 'dialog_button.dart';
diff --git a/lib/src/ui/dialog/dialog.dart b/lib/src/ui/dialog/dialog.dart
index 2a4640f..8fcf82d 100644
--- a/lib/src/ui/dialog/dialog.dart
+++ b/lib/src/ui/dialog/dialog.dart
@@ -1,7 +1,5 @@
-import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:clipboard/clipboard.dart';
import 'package:fluent_ui/fluent_ui.dart';
-import 'package:flutter/material.dart';
import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
import 'dialog_button.dart';
@@ -24,10 +22,6 @@ class GenericDialog extends AbstractDialog {
Widget build(BuildContext context) {
return Stack(
children: [
- MoveWindow(
- child: const SizedBox.expand(),
- ),
-
ContentDialog(
style: ContentDialogThemeData(
padding: padding ?? const EdgeInsets.only(left: 20, right: 20, top: 15.0, bottom: 5.0)
diff --git a/lib/src/ui/dialog/game_dialogs.dart b/lib/src/ui/dialog/game_dialogs.dart
index 15146af..0953595 100644
--- a/lib/src/ui/dialog/game_dialogs.dart
+++ b/lib/src/ui/dialog/game_dialogs.dart
@@ -1,7 +1,7 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:reboot_launcher/src/model/fortnite_version.dart';
-import '../../../main.dart';
+import 'package:reboot_launcher/main.dart';
import 'dialog.dart';
const String _unsupportedServerError = "The build you are currently using is not supported by Reboot. "
diff --git a/lib/src/ui/dialog/server_dialogs.dart b/lib/src/ui/dialog/server_dialogs.dart
index b2783ac..d4e580e 100644
--- a/lib/src/ui/dialog/server_dialogs.dart
+++ b/lib/src/ui/dialog/server_dialogs.dart
@@ -1,14 +1,12 @@
import 'package:fluent_ui/fluent_ui.dart';
-
import 'package:reboot_launcher/src/model/server_type.dart';
-import 'package:reboot_launcher/src/util/os.dart';
import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
import 'package:sync/semaphore.dart';
import 'package:url_launcher/url_launcher.dart';
-import '../../../main.dart';
-import '../../util/server.dart';
-import '../controller/server_controller.dart';
+import 'package:reboot_launcher/main.dart';
+import 'package:reboot_launcher/src/util/server.dart';
+import 'package:reboot_launcher/src/ui/controller/server_controller.dart';
import 'dialog.dart';
import 'dialog_button.dart';
diff --git a/lib/src/ui/dialog/snackbar.dart b/lib/src/ui/dialog/snackbar.dart
index 05ff95a..4134bdf 100644
--- a/lib/src/ui/dialog/snackbar.dart
+++ b/lib/src/ui/dialog/snackbar.dart
@@ -1,6 +1,6 @@
import 'package:fluent_ui/fluent_ui.dart';
-import '../../../main.dart';
+import 'package:reboot_launcher/main.dart';
void showMessage(String text){
showSnackbar(
diff --git a/lib/src/ui/page/browse_page.dart b/lib/src/ui/page/browse_page.dart
index 81d237d..3f3ed5c 100644
--- a/lib/src/ui/page/browse_page.dart
+++ b/lib/src/ui/page/browse_page.dart
@@ -1,8 +1,4 @@
import 'package:fluent_ui/fluent_ui.dart';
-import 'package:get/get.dart';
-import 'package:reboot_launcher/src/ui/controller/hosting_controller.dart';
-import 'package:reboot_launcher/src/ui/widget/home/launch_button.dart';
-import 'package:reboot_launcher/src/ui/widget/home/version_selector.dart';
import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
diff --git a/lib/src/ui/page/home_page.dart b/lib/src/ui/page/home_page.dart
index 9e04ab4..fc4bbd4 100644
--- a/lib/src/ui/page/home_page.dart
+++ b/lib/src/ui/page/home_page.dart
@@ -1,18 +1,16 @@
-import 'package:bitsdojo_window/bitsdojo_window.dart' hide WindowBorder;
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
-import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:reboot_launcher/main.dart';
-import 'package:reboot_launcher/src/util/os.dart';
import 'package:reboot_launcher/src/ui/page/launcher_page.dart';
import 'package:reboot_launcher/src/ui/page/server_page.dart';
import 'package:reboot_launcher/src/ui/page/settings_page.dart';
-import 'package:window_manager/window_manager.dart';
+import 'package:reboot_launcher/src/ui/widget/shared/profile_widget.dart';
-import '../controller/game_controller.dart';
-import '../controller/settings_controller.dart';
-import '../widget/os/window_border.dart';
-import '../widget/os/window_buttons.dart';
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
+import 'package:reboot_launcher/src/ui/widget/os/window_border.dart';
+import 'package:reboot_launcher/src/ui/widget/os/window_title_bar.dart';
+import 'package:window_manager/window_manager.dart';
import 'hosting_page.dart';
import 'info_page.dart';
@@ -25,8 +23,8 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State with WindowListener, AutomaticKeepAliveClientMixin {
static const double _kDefaultPadding = 12.0;
- static const int _kPagesLength = 5;
-
+ static const int _kPagesLength = 6;
+
final SettingsController _settingsController = Get.find();
final GlobalKey _searchKey = GlobalKey();
final FocusNode _searchFocusNode = FocusNode();
@@ -41,6 +39,7 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA
@override
void initState() {
+ windowManager.show();
windowManager.addListener(this);
_searchController.addListener(_onSearch);
super.initState();
@@ -52,7 +51,8 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA
return;
}
- _searchItems.value = _allItems.whereType()
+ _searchItems.value = _allItems
+ .whereType()
.where((item) => (item.title as Text).data!.toLowerCase().contains(searchValue.toLowerCase()))
.toList()
.cast();
@@ -84,73 +84,88 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA
@override
void onWindowMoved() {
- _settingsController.saveWindowOffset(appWindow.position);
+ windowManager.getPosition()
+ .then((value) => _settingsController.saveWindowOffset(value));
super.onWindowMoved();
}
@override
Widget build(BuildContext context) {
super.build(context);
- return Stack(
- children: [
- LayoutBuilder(
- builder: (context, specs) => Obx(() => NavigationView(
- paneBodyBuilder: (pane, body) => Padding(
- padding: const EdgeInsets.all(_kDefaultPadding),
- child: body
+ return Stack(children: [
+ LayoutBuilder(
+ builder: (context, specs) => Obx(() => NavigationPaneTheme(
+ data: NavigationPaneThemeData(
+ backgroundColor: FluentTheme.of(context).micaBackgroundColor.withOpacity(0.9),
),
- appBar: NavigationAppBar(
- title: _draggableArea,
- actions: WindowTitleBar(focused: _focused()),
- automaticallyImplyLeading: false,
- leading: _backButton
- ),
- pane: NavigationPane(
- key: appKey,
- selected: _selectedIndex,
- onChanged: _onIndexChanged,
- displayMode: specs.biggest.width <= 1536 ? PaneDisplayMode.compact : PaneDisplayMode.open,
- items: _items,
- footerItems: _footerItems,
- autoSuggestBox: _autoSuggestBox,
- autoSuggestBoxReplacement: const Icon(FluentIcons.search),
- ),
- onOpenSearch: () => _searchFocusNode.requestFocus(),
- transitionBuilder: (child, animation) => child
- ))
- ),
- if(isWin11)
- Obx(() => _focused.value ? const WindowBorder() : const SizedBox())
- ]
- );
+ child: NavigationView(
+ paneBodyBuilder: (pane, body) => Padding(
+ padding: const EdgeInsets.all(_kDefaultPadding),
+ child: body
+ ),
+ appBar: NavigationAppBar(
+ height: 32,
+ title: _draggableArea,
+ actions: WindowTitleBar(focused: _focused()),
+ automaticallyImplyLeading: false,
+ leading: _backButton
+ ),
+ pane: NavigationPane(
+ key: appKey,
+ selected: _selectedIndex,
+ onChanged: _onIndexChanged,
+ menuButton: const SizedBox(),
+ displayMode: PaneDisplayMode.open,
+ items: _items,
+ header: ProfileWidget(),
+ footerItems: _footerItems,
+ autoSuggestBox: _autoSuggestBox,
+ autoSuggestBoxReplacement: const Icon(FluentIcons.search),
+ ),
+ contentShape: const RoundedRectangleBorder(),
+ onOpenSearch: () => _searchFocusNode.requestFocus(),
+ transitionBuilder: (child, animation) => child),
+ )
+ )
+ ),
+ if (isWin11)
+ Obx(() => _focused.value ? const WindowBorder() : const SizedBox())
+ ]);
}
+ GestureDetector get _draggableArea => GestureDetector(
+ onDoubleTap: () async => await windowManager.isMaximized() ? await windowManager.restore() : await windowManager.maximize(),
+ onHorizontalDragStart: (event) => windowManager.startDragging(),
+ onVerticalDragStart: (event) => windowManager.startDragging()
+ );
+
Widget get _backButton => Obx(() {
- for(var entry in _navigationStatus){
+ for (var entry in _navigationStatus) {
entry.value;
}
var onBack = _onBack();
- return PaneItem(
- enabled: onBack != null,
- icon: const Icon(FluentIcons.back, size: 14.0),
- body: const SizedBox.shrink(),
- ).build(
- context,
- false,
- onBack,
- displayMode: PaneDisplayMode.compact
+ return Padding(
+ padding: const EdgeInsets.only(top: 8.0),
+ child: Button(
+ onPressed: onBack,
+ style: ButtonStyle(
+ backgroundColor: ButtonState.all(Colors.transparent),
+ border: ButtonState.all(BorderSide(color: Colors.transparent))
+ ),
+ child: const Icon(FluentIcons.back, size: 13.0)
+ )
);
});
Function()? _onBack() {
var navigator = _navigators[_settingsController.index.value].currentState;
- if(navigator == null || !navigator.mounted || !navigator.canPop()){
+ if (navigator == null || !navigator.mounted || !navigator.canPop()) {
return null;
}
var status = _navigationStatus[_settingsController.index.value];
- if(status.value <= 0){
+ if (status.value <= 0) {
return null;
}
@@ -165,17 +180,15 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA
_settingsController.index.value = index;
}
- TextBox get _autoSuggestBox => TextBox(
- key: _searchKey,
- controller: _searchController,
- placeholder: 'Search',
- focusNode: _searchFocusNode
- );
-
- GestureDetector get _draggableArea => GestureDetector(
- onDoubleTap: () => appWindow.maximizeOrRestore(),
- onHorizontalDragStart: (event) => appWindow.startDragging(),
- onVerticalDragStart: (event) => appWindow.startDragging()
+ Widget get _autoSuggestBox => Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: TextBox(
+ key: _searchKey,
+ controller: _searchController,
+ placeholder: 'Find a setting',
+ focusNode: _searchFocusNode,
+ autofocus: true
+ ),
);
int? get _selectedIndex {
@@ -184,11 +197,12 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA
return _settingsController.index();
}
- if(_settingsController.index() >= _allItems.length){
+ if (_settingsController.index() >= _allItems.length) {
return null;
}
- var indexOnScreen = searchItems.indexOf(_allItems[_settingsController.index()]);
+ var indexOnScreen =
+ searchItems.indexOf(_allItems[_settingsController.index()]);
if (indexOnScreen.isNegative) {
return null;
}
@@ -199,36 +213,75 @@ class _HomePageState extends State with WindowListener, AutomaticKeepA
List get _allItems => [..._items, ..._footerItems];
List get _footerItems => searchValue.isNotEmpty ? [] : [
- PaneItem(
- title: const Text("Settings"),
- icon: const Icon(FluentIcons.settings),
- body: SettingsPage()
- )
+ PaneItem(
+ title: const Text("Downloads"),
+ icon: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SizedBox.square(
+ dimension: 24,
+ child: Image.asset("assets/images/download.png")
+ )
+ ),
+ body: const SettingsPage()
+ ),
+ PaneItem(
+ title: const Text("Settings"),
+ icon: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SizedBox.square(
+ dimension: 24,
+ child: Image.asset("assets/images/settings.png")
+ )
+ ),
+ body: const SettingsPage()
+ )
];
List get _items => _searchItems() ?? [
- PaneItem(
- title: const Text("Tutorial"),
- icon: const Icon(FluentIcons.info),
- body: InfoPage(_navigators[0], _navigationStatus[0])
- ),
PaneItem(
title: const Text("Play"),
- icon: const Icon(FluentIcons.game),
- body: LauncherPage(_navigators[1], _navigationStatus[1])
+ icon: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SizedBox.square(
+ dimension: 24,
+ child: Image.asset("assets/images/play.png")
+ )
+ ),
+ body: LauncherPage(_navigators[0], _navigationStatus[0])
),
-
PaneItem(
title: const Text("Host"),
- icon: const Icon(FluentIcons.server_processes),
- body: HostingPage(_navigators[2], _navigationStatus[2])
+ icon: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SizedBox.square(
+ dimension: 24,
+ child: Image.asset("assets/images/host.png")
+ )
+ ),
+ body: HostingPage(_navigators[1], _navigationStatus[1])
),
-
PaneItem(
- title: const Text("Backend"),
- icon: const Icon(FluentIcons.user_window),
- body: ServerPage(_navigators[3], _navigationStatus[3])
+ title: const Text("Authenticator"),
+ icon: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SizedBox.square(
+ dimension: 24,
+ child: Image.asset("assets/images/cloud.png")
+ )
+ ),
+ body: ServerPage(_navigators[2], _navigationStatus[2])
),
+ PaneItem(
+ title: const Text("Tutorial"),
+ icon: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SizedBox.square(
+ dimension: 24,
+ child: Image.asset("assets/images/info.png")
+ )
+ ),
+ body: InfoPage(_navigators[3], _navigationStatus[3])
+ )
];
String get searchValue => _searchController.text;
diff --git a/lib/src/ui/page/hosting_page.dart b/lib/src/ui/page/hosting_page.dart
index d162942..5649032 100644
--- a/lib/src/ui/page/hosting_page.dart
+++ b/lib/src/ui/page/hosting_page.dart
@@ -3,10 +3,10 @@ import 'package:get/get.dart';
import 'package:reboot_launcher/src/ui/controller/hosting_controller.dart';
import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
import 'package:reboot_launcher/src/ui/widget/home/launch_button.dart';
-import 'package:reboot_launcher/src/ui/widget/home/version_selector.dart';
import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
+import 'package:reboot_launcher/src/ui/widget/home/version_selector.dart';
-import '../../model/update_status.dart';
+import 'package:reboot_launcher/src/model/update_status.dart';
import 'browse_page.dart';
class HostingPage extends StatefulWidget {
@@ -38,7 +38,7 @@ class _HostingPageState extends State with AutomaticKeepAliveClient
mainAxisAlignment: MainAxisAlignment.center,
children: [
ProgressRing(),
- SizedBox(height: 16.0),
+ SizedBox(height: 8.0),
Text("Updating Reboot DLL...")
],
),
@@ -97,7 +97,7 @@ class _HostPageState extends State<_HostPage> with AutomaticKeepAliveClientMixin
child: _hostingController.updateStatus.value == UpdateStatus.error ? _updateError : _rebootGuiInfo,
)),
const SizedBox(
- height: 16.0
+ height: 8.0
),
SettingTile(
title: "Game Server",
@@ -135,7 +135,7 @@ class _HostPageState extends State<_HostPage> with AutomaticKeepAliveClientMixin
],
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Version",
@@ -163,7 +163,7 @@ class _HostPageState extends State<_HostPage> with AutomaticKeepAliveClientMixin
]
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Browse available servers",
diff --git a/lib/src/ui/page/info_page.dart b/lib/src/ui/page/info_page.dart
index 2fad66c..3274a8f 100644
--- a/lib/src/ui/page/info_page.dart
+++ b/lib/src/ui/page/info_page.dart
@@ -1,20 +1,16 @@
import 'dart:async';
import 'package:fluent_ui/fluent_ui.dart';
-import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
import 'package:reboot_launcher/src/ui/widget/home/launch_button.dart';
import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
import 'package:reboot_launcher/src/util/checks.dart';
-import 'package:reboot_launcher/src/util/server.dart';
-import '../../util/os.dart';
-import '../controller/game_controller.dart';
-import '../controller/settings_controller.dart';
-import '../dialog/dialog.dart';
-import '../dialog/dialog_button.dart';
-import '../widget/home/version_selector.dart';
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
+import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
+import 'package:reboot_launcher/src/ui/widget/home/version_selector.dart';
class InfoPage extends StatefulWidget {
final GlobalKey navigatorKey;
@@ -219,7 +215,7 @@ class _PlayPageState extends State<_PlayPage> {
],
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: '2. Download Fortnite',
@@ -255,7 +251,7 @@ class _PlayPageState extends State<_PlayPage> {
],
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
StreamBuilder(
stream: _remoteGameServerStream.stream,
diff --git a/lib/src/ui/page/launcher_page.dart b/lib/src/ui/page/launcher_page.dart
index dddb996..1d84ecb 100644
--- a/lib/src/ui/page/launcher_page.dart
+++ b/lib/src/ui/page/launcher_page.dart
@@ -1,20 +1,8 @@
-
-
-import 'dart:async';
-
import 'package:fluent_ui/fluent_ui.dart';
-import 'package:flutter/material.dart' show Icons;
import 'package:get/get.dart';
-import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
-import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
-import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
import 'package:reboot_launcher/src/ui/page/browse_page.dart';
-import 'package:reboot_launcher/src/ui/widget/home/launch_button.dart';
-import 'package:reboot_launcher/src/ui/widget/home/version_selector.dart';
-import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
+import 'package:reboot_launcher/src/ui/page/play_page.dart';
-import '../../util/checks.dart';
-import '../../util/os.dart';
class LauncherPage extends StatefulWidget {
final GlobalKey navigatorKey;
@@ -48,185 +36,11 @@ class _LauncherPageState extends State with AutomaticKeepAliveClie
Widget _createScreen(String? name) {
switch(name){
case "home":
- return _GamePage(widget.navigatorKey, widget.nestedNavigation);
+ return PlayPage(widget.navigatorKey, widget.nestedNavigation);
case "browse":
return const BrowsePage();
default:
throw Exception("Unknown page: $name");
}
}
-}
-
-class _GamePage extends StatefulWidget {
- final GlobalKey navigatorKey;
- final RxInt nestedNavigation;
- const _GamePage(this.navigatorKey, this.nestedNavigation, {Key? key}) : super(key: key);
-
- @override
- State<_GamePage> createState() => _GamePageState();
-}
-
-class _GamePageState extends State<_GamePage> {
- final GameController _gameController = Get.find();
- final SettingsController _settingsController = Get.find();
- late final RxBool _showPasswordTrailing = RxBool(_gameController.password.text.isNotEmpty);
- final StreamController _matchmakingStream = StreamController();
-
- @override
- void initState() {
- _gameController.password.addListener(() => _matchmakingStream.add(null));
- _settingsController.matchmakingIp.addListener(() => _matchmakingStream.add(null));
- super.initState();
- }
-
- @override
- Widget build(BuildContext context) => Column(
- children: [
- Expanded(
- child: ListView(
- children: [
- SettingTile(
- title: "Credentials",
- subtitle: "Your in-game login credentials",
- expandedContentSpacing: 0,
- expandedContent: [
- SettingTile(
- title: "Username",
- subtitle: "The username that other players will see when you are in game",
- isChild: true,
- content: TextFormBox(
- placeholder: "Username",
- controller: _gameController.username,
- autovalidateMode: AutovalidateMode.always
- ),
- ),
- SettingTile(
- title: "Password",
- subtitle: "The password of your account, only used if the backend requires it",
- isChild: true,
- content: Obx(() => TextFormBox(
- placeholder: "Password",
- controller: _gameController.password,
- autovalidateMode: AutovalidateMode.always,
- obscureText: !_gameController.showPassword.value,
- enableSuggestions: false,
- autocorrect: false,
- onChanged: (text) => _showPasswordTrailing.value = text.isNotEmpty,
- suffix: Button(
- onPressed: () => _gameController.showPassword.value = !_gameController.showPassword.value,
- style: ButtonStyle(
- shape: ButtonState.all(const CircleBorder()),
- backgroundColor: ButtonState.all(Colors.transparent)
- ),
- child: Icon(
- _gameController.showPassword.value ? Icons.visibility_off : Icons.visibility,
- color: _showPasswordTrailing.value ? null : Colors.transparent
- ),
- )
- ))
- )
- ],
- ),
- const SizedBox(
- height: 16.0,
- ),
- StreamBuilder(
- stream: _matchmakingStream.stream,
- builder: (context, value) =>
- SettingTile(
- title: "Matchmaking host",
- subtitle: "Enter the IP address of the game server hosting the match",
- content: TextFormBox(
- placeholder: "IP:PORT",
- controller: _settingsController.matchmakingIp,
- validator: checkMatchmaking,
- autovalidateMode: AutovalidateMode.always
- ),
- expandedContent: [
- SettingTile(
- title: "Automatically start game server",
- subtitle: "This option is available when the matchmaker is set to localhost",
- contentWidth: null,
- content: !isLocalHost(_settingsController.matchmakingIp.text) || _gameController.password.text.isNotEmpty ? _disabledAutoGameServerSwitch : _autoGameServerSwitch,
- isChild: true
- ),
- SettingTile(
- title: "Browse available servers",
- subtitle: "Discover new game servers that fit your play-style",
- content: Button(
- onPressed: () {
- widget.navigatorKey.currentState?.pushNamed('browse');
- widget.nestedNavigation.value += 1;
- },
- child: const Text("Browse")
- ),
- isChild: true
- )
- ]
- )
- ),
- const SizedBox(
- height: 16.0,
- ),
- SettingTile(
- title: "Version",
- subtitle: "Select the version of Fortnite you want to play",
- content: const VersionSelector(),
- expandedContent: [
- SettingTile(
- title: "Add a version from this PC's local storage",
- subtitle: "Versions coming from your local disk are not guaranteed to work",
- content: Button(
- onPressed: () => VersionSelector.openAddDialog(context),
- child: const Text("Add build"),
- ),
- isChild: true
- ),
- SettingTile(
- title: "Download any version from the cloud",
- subtitle: "A curated list of supported versions by Project Reboot",
- content: Button(
- onPressed: () => VersionSelector.openDownloadDialog(context),
- child: const Text("Download"),
- ),
- isChild: true
- )
- ]
- )
- ],
- ),
- ),
- const SizedBox(
- height: 8.0,
- ),
- const LaunchButton(
- host: false
- )
- ],
- );
-
- Widget get _disabledAutoGameServerSwitch => Container(
- foregroundDecoration: const BoxDecoration(
- color: Colors.grey,
- backgroundBlendMode: BlendMode.saturation,
- ),
- child: _autoGameServerSwitch,
- );
-
- Widget get _autoGameServerSwitch => Obx(() => ToggleSwitch(
- checked: _gameController.autoStartGameServer() && isLocalHost(_settingsController.matchmakingIp.text) && _gameController.password.text.isEmpty,
- onChanged: (value) {
- if(!isLocalHost(_settingsController.matchmakingIp.text)){
- showMessage("This option isn't available when the matchmaker isn't set to 127.0.0.1");
- return;
- }
-
- if(_gameController.password.text.isNotEmpty){
- showMessage("This option isn't available when the password isn't empty(LawinV2)");
- return;
- }
-
- _gameController.autoStartGameServer.value = value;
- }
- ));
}
\ No newline at end of file
diff --git a/lib/src/ui/page/play_page.dart b/lib/src/ui/page/play_page.dart
new file mode 100644
index 0000000..29af481
--- /dev/null
+++ b/lib/src/ui/page/play_page.dart
@@ -0,0 +1,154 @@
+import 'dart:async';
+
+import 'package:fluent_ui/fluent_ui.dart';
+import 'package:get/get.dart';
+import 'package:get/get_rx/src/rx_types/rx_types.dart';
+
+import 'package:reboot_launcher/src/util/checks.dart';
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
+import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
+import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
+import 'package:reboot_launcher/src/ui/widget/home/launch_button.dart';
+import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
+import 'package:reboot_launcher/src/ui/widget/home/version_selector.dart';
+
+class PlayPage extends StatefulWidget {
+ final GlobalKey navigatorKey;
+ final RxInt nestedNavigation;
+ const PlayPage(this.navigatorKey, this.nestedNavigation, {Key? key}) : super(key: key);
+
+ @override
+ State createState() => _PlayPageState();
+}
+
+class _PlayPageState extends State {
+ final GameController _gameController = Get.find();
+ final SettingsController _settingsController = Get.find();
+ final StreamController _matchmakingStream = StreamController();
+
+ @override
+ void initState() {
+ _gameController.password.addListener(() => _matchmakingStream.add(null));
+ _settingsController.matchmakingIp.addListener(() =>
+ _matchmakingStream.add(null));
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) => Column(
+ children: [
+ Expanded(
+ child: ListView(
+ children: [
+ SettingTile(
+ title: "Version",
+ subtitle: "Select the version of Fortnite you want to play",
+ content: const VersionSelector(),
+ expandedContent: [
+ SettingTile(
+ title: "Add a version from this PC's local storage",
+ subtitle: "Versions coming from your local disk are not guaranteed to work",
+ content: Button(
+ onPressed: () =>
+ VersionSelector.openAddDialog(context),
+ child: const Text("Add build"),
+ ),
+ isChild: true
+ ),
+ SettingTile(
+ title: "Download any version from the cloud",
+ subtitle: "A curated list of supported versions by Project Reboot",
+ content: Button(
+ onPressed: () =>
+ VersionSelector.openDownloadDialog(context),
+ child: const Text("Download"),
+ ),
+ isChild: true
+ )
+ ]
+ ),
+ const SizedBox(
+ height: 8.0,
+ ),
+ StreamBuilder(
+ stream: _matchmakingStream.stream,
+ builder: (context, value) =>
+ SettingTile(
+ title: "Matchmaking host",
+ subtitle: "Enter the IP address of the game server hosting the match",
+ content: TextFormBox(
+ placeholder: "IP:PORT",
+ controller: _settingsController.matchmakingIp,
+ validator: checkMatchmaking,
+ autovalidateMode: AutovalidateMode.always
+ ),
+ expandedContent: [
+ SettingTile(
+ title: "Automatically start game server",
+ subtitle: "This option is available when the matchmaker is set to localhost",
+ contentWidth: null,
+ content: !isLocalHost(
+ _settingsController.matchmakingIp.text) ||
+ _gameController.password.text.isNotEmpty
+ ? _disabledAutoGameServerSwitch
+ : _autoGameServerSwitch,
+ isChild: true
+ ),
+ SettingTile(
+ title: "Browse available servers",
+ subtitle: "Discover new game servers that fit your play-style",
+ content: Button(
+ onPressed: () {
+ widget.navigatorKey.currentState
+ ?.pushNamed('browse');
+ widget.nestedNavigation.value += 1;
+ },
+ child: const Text("Browse")
+ ),
+ isChild: true
+ )
+ ]
+ )
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 8.0,
+ ),
+ const LaunchButton(
+ host: false
+ )
+ ],
+ );
+
+ Widget get _disabledAutoGameServerSwitch => Container(
+ foregroundDecoration: const BoxDecoration(
+ color: Colors.grey,
+ backgroundBlendMode: BlendMode.saturation,
+ ),
+ child: _autoGameServerSwitch,
+ );
+
+ Widget get _autoGameServerSwitch => Obx(() => ToggleSwitch(
+ checked: _gameController.autoStartGameServer() &&
+ isLocalHost(_settingsController.matchmakingIp.text) &&
+ _gameController.password.text.isEmpty,
+ onChanged: (value) {
+ if (!isLocalHost(_settingsController.matchmakingIp.text)) {
+ showMessage(
+ "This option isn't available when the matchmaker isn't set to 127.0.0.1");
+ return;
+ }
+
+ if (_gameController.password.text.isNotEmpty) {
+ showMessage(
+ "This option isn't available when the password isn't empty(LawinV2)");
+ return;
+ }
+
+ _gameController.autoStartGameServer.value = value;
+ }
+ ));
+}
\ No newline at end of file
diff --git a/lib/src/ui/page/server_page.dart b/lib/src/ui/page/server_page.dart
index ece1285..d481271 100644
--- a/lib/src/ui/page/server_page.dart
+++ b/lib/src/ui/page/server_page.dart
@@ -1,15 +1,15 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:reboot_launcher/src/model/server_type.dart';
-import 'package:reboot_launcher/src/util/server.dart';
import 'package:reboot_launcher/src/ui/controller/server_controller.dart';
-import 'package:reboot_launcher/src/ui/widget/server/server_type_selector.dart';
import 'package:reboot_launcher/src/ui/widget/server/server_button.dart';
+import 'package:reboot_launcher/src/ui/widget/server/server_type_selector.dart';
+import 'package:reboot_launcher/src/util/server.dart';
import 'package:url_launcher/url_launcher.dart';
-import '../dialog/dialog.dart';
-import '../dialog/dialog_button.dart';
-import '../widget/home/setting_tile.dart';
+import 'package:reboot_launcher/src/ui/dialog/dialog.dart';
+import 'package:reboot_launcher/src/ui/dialog/dialog_button.dart';
+import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
class ServerPage extends StatefulWidget {
final GlobalKey navigatorKey;
@@ -43,7 +43,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMi
),
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Host",
@@ -55,7 +55,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMi
)
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Port",
@@ -67,7 +67,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMi
)
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Type",
@@ -75,7 +75,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMi
content: ServerTypeSelector()
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Detached",
@@ -87,7 +87,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMi
))
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Server files",
@@ -98,7 +98,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMi
)
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Reset Backend",
diff --git a/lib/src/ui/page/settings_page.dart b/lib/src/ui/page/settings_page.dart
index 10a3b20..d4fee61 100644
--- a/lib/src/ui/page/settings_page.dart
+++ b/lib/src/ui/page/settings_page.dart
@@ -1,5 +1,4 @@
import 'package:fluent_ui/fluent_ui.dart';
-import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
@@ -7,12 +6,10 @@ import 'package:reboot_launcher/src/ui/dialog/dialog_button.dart';
import 'package:reboot_launcher/src/ui/widget/shared/file_selector.dart';
import 'package:url_launcher/url_launcher.dart';
-
-import '../../util/checks.dart';
-import '../../util/os.dart';
-import '../../util/selector.dart';
-import '../dialog/dialog.dart';
-import '../widget/home/setting_tile.dart';
+import 'package:reboot_launcher/src/util/checks.dart';
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/ui/dialog/dialog.dart';
+import 'package:reboot_launcher/src/ui/widget/home/setting_tile.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({Key? key}) : super(key: key);
@@ -56,7 +53,7 @@ class _SettingsPageState extends State with AutomaticKeepAliveClie
],
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Automatic updates",
@@ -82,7 +79,7 @@ class _SettingsPageState extends State with AutomaticKeepAliveClie
]
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Custom launch arguments",
@@ -93,7 +90,7 @@ class _SettingsPageState extends State with AutomaticKeepAliveClie
)
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Create a bug report",
@@ -104,7 +101,7 @@ class _SettingsPageState extends State with AutomaticKeepAliveClie
)
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Reset settings",
@@ -134,7 +131,7 @@ class _SettingsPageState extends State with AutomaticKeepAliveClie
)
),
const SizedBox(
- height: 16.0,
+ height: 8.0,
),
SettingTile(
title: "Version status",
diff --git a/lib/src/ui/widget/home/build_selector.dart b/lib/src/ui/widget/home/build_selector.dart
index 4bf8038..45d9f9f 100644
--- a/lib/src/ui/widget/home/build_selector.dart
+++ b/lib/src/ui/widget/home/build_selector.dart
@@ -1,7 +1,7 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
-import 'package:reboot_launcher/src/ui/controller/build_controller.dart';
import 'package:reboot_launcher/src/model/fortnite_build.dart';
+import 'package:reboot_launcher/src/ui/controller/build_controller.dart';
class BuildSelector extends StatefulWidget {
final Function() onSelected;
diff --git a/lib/src/ui/widget/home/launch_button.dart b/lib/src/ui/widget/home/launch_button.dart
index 75c3552..cb60ebc 100644
--- a/lib/src/ui/widget/home/launch_button.dart
+++ b/lib/src/ui/widget/home/launch_button.dart
@@ -1,32 +1,29 @@
import 'dart:async';
-import 'dart:collection';
import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
+import 'package:path/path.dart' as path;
import 'package:process_run/shell.dart';
+import 'package:reboot_launcher/src/../main.dart';
+import 'package:reboot_launcher/src/model/fortnite_version.dart';
+import 'package:reboot_launcher/src/model/game_instance.dart';
+import 'package:reboot_launcher/src/model/server_type.dart';
import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
import 'package:reboot_launcher/src/ui/controller/hosting_controller.dart';
import 'package:reboot_launcher/src/ui/controller/server_controller.dart';
+import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
import 'package:reboot_launcher/src/ui/dialog/dialog.dart';
import 'package:reboot_launcher/src/ui/dialog/game_dialogs.dart';
import 'package:reboot_launcher/src/ui/dialog/server_dialogs.dart';
-import 'package:reboot_launcher/src/model/fortnite_version.dart';
-import 'package:reboot_launcher/src/model/server_type.dart';
-import 'package:reboot_launcher/src/util/os.dart';
-import 'package:reboot_launcher/src/util/injector.dart';
-import 'package:reboot_launcher/src/util/patcher.dart';
-import 'package:reboot_launcher/src/util/server.dart';
-import 'package:path/path.dart' as path;
-
-import 'package:reboot_launcher/src/../main.dart';
-import 'package:reboot_launcher/src/ui/controller/settings_controller.dart';
import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
-import 'package:reboot_launcher/src/model/game_instance.dart';
+import 'package:reboot_launcher/src/util/injector.dart';
+import 'package:reboot_launcher/src/util/os.dart';
+import 'package:reboot_launcher/src/util/server.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
-import '../../../util/process.dart';
+import 'package:reboot_launcher/src/util/process.dart';
class LaunchButton extends StatefulWidget {
final bool host;
@@ -124,7 +121,8 @@ class _LaunchButtonState extends State {
try {
var version = _gameController.selectedVersion!;
- if(version.executable?.path == null){
+ var executable = await version.executable;
+ if(executable == null){
showMissingBuildError(version);
_onStop(widget.host);
return;
@@ -136,9 +134,6 @@ class _LaunchButtonState extends State {
return;
}
- await compute(patchHeadless, version.executable!);
- // Is this needed? await compute(patchMatchmaking, version.executable!);
-
var automaticallyStartedServer = await _startMatchMakingServer();
await _startGameProcesses(version, widget.host, automaticallyStartedServer);
@@ -156,7 +151,14 @@ class _LaunchButtonState extends State {
_setStarted(host, true);
var launcherProcess = await _createLauncherProcess(version);
var eacProcess = await _createEacProcess(version);
- var gameProcess = await _createGameProcess(version.executable!.path, host);
+ var executable = await version.executable;
+ if(executable == null){
+ showMissingBuildError(version);
+ _onStop(widget.host);
+ return;
+ }
+
+ var gameProcess = await _createGameProcess(executable.path, host);
var watchDogProcess = _createWatchdogProcess(gameProcess, launcherProcess, eacProcess);
var instance = GameInstance(gameProcess, launcherProcess, eacProcess, watchDogProcess, hasChildServer);
if(host){
diff --git a/lib/src/ui/widget/home/setting_tile.dart b/lib/src/ui/widget/home/setting_tile.dart
index 28381f4..26ccca8 100644
--- a/lib/src/ui/widget/home/setting_tile.dart
+++ b/lib/src/ui/widget/home/setting_tile.dart
@@ -1,5 +1,4 @@
import 'package:fluent_ui/fluent_ui.dart';
-import 'package:reboot_launcher/src/ui/widget/shared/fluent_card.dart';
class SettingTile extends StatefulWidget {
static const double kDefaultContentWidth = 200.0;
@@ -42,19 +41,17 @@ class _SettingTileState extends State {
return _contentCard;
}
- return Mica(
- elevation: 1,
- child: Expander(
- initiallyExpanded: true,
- contentBackgroundColor: FluentTheme.of(context).menuColor,
- headerShape: (open) => const RoundedRectangleBorder(
- borderRadius: BorderRadius.vertical(top: Radius.circular(4.0)),
- ),
- header: _header,
- headerHeight: widget.expandedContentHeaderHeight,
- trailing: _trailing,
- content: _content
- ),
+ return Expander(
+ initiallyExpanded: true,
+ headerShape: (open) => const RoundedRectangleBorder(
+ borderRadius: BorderRadius.vertical(top: Radius.circular(4.0)),
+ ),
+ header: SizedBox(
+ height: widget.expandedContentHeaderHeight,
+ child: _header
+ ),
+ trailing: _trailing,
+ content: _content
);
}
@@ -90,8 +87,9 @@ class _SettingTileState extends State {
);
}
- return FluentCard(
- child: _contentCardBody,
+ return Card(
+ borderRadius: const BorderRadius.vertical(top: Radius.circular(4.0)),
+ child: _contentCardBody
);
}
diff --git a/lib/src/ui/widget/home/version_selector.dart b/lib/src/ui/widget/home/version_selector.dart
index 2b07282..cdb634e 100644
--- a/lib/src/ui/widget/home/version_selector.dart
+++ b/lib/src/ui/widget/home/version_selector.dart
@@ -4,18 +4,18 @@ import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/gestures.dart';
import 'package:get/get.dart';
+import 'package:reboot_launcher/src/model/fortnite_version.dart';
import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
+import 'package:reboot_launcher/src/ui/dialog/add_local_version.dart';
+import 'package:reboot_launcher/src/ui/dialog/add_server_version.dart';
import 'package:reboot_launcher/src/ui/dialog/dialog.dart';
import 'package:reboot_launcher/src/ui/dialog/dialog_button.dart';
-import 'package:reboot_launcher/src/model/fortnite_version.dart';
-import 'package:reboot_launcher/src/ui/dialog/add_local_version.dart';
import 'package:reboot_launcher/src/ui/widget/shared/smart_check_box.dart';
+import 'package:reboot_launcher/src/util/checks.dart';
import 'package:reboot_launcher/src/util/os.dart';
import 'package:url_launcher/url_launcher.dart';
-import 'package:reboot_launcher/src/ui/dialog/add_server_version.dart';
-import 'package:reboot_launcher/src/util/checks.dart';
-import '../shared/file_selector.dart';
+import 'package:reboot_launcher/src/ui/widget/shared/file_selector.dart';
class VersionSelector extends StatefulWidget {
const VersionSelector({Key? key}) : super(key: key);
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/src/icons/icons.dart b/lib/src/ui/widget/os/icons.dart
similarity index 86%
rename from dependencies/bitsdojo_window-0.1.5/lib/src/icons/icons.dart
rename to lib/src/ui/widget/os/icons.dart
index c0b00eb..68ece22 100644
--- a/dependencies/bitsdojo_window-0.1.5/lib/src/icons/icons.dart
+++ b/lib/src/ui/widget/os/icons.dart
@@ -7,7 +7,9 @@ import 'package:flutter/widgets.dart';
/// Close
class CloseIcon extends StatelessWidget {
final Color color;
- CloseIcon({Key? key, required this.color}) : super(key: key);
+
+ const CloseIcon({Key? key, required this.color}) : super(key: key);
+
@override
Widget build(BuildContext context) => Align(
alignment: Alignment.topLeft,
@@ -28,13 +30,16 @@ class CloseIcon extends StatelessWidget {
/// Maximize
class MaximizeIcon extends StatelessWidget {
final Color color;
- MaximizeIcon({Key? key, required this.color}) : super(key: key);
+
+ 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);
@@ -45,22 +50,25 @@ class _MaximizePainter extends _IconPainter {
/// Restore
class RestoreIcon extends StatelessWidget {
final Color color;
- RestoreIcon({
+
+ 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(Offset(2, 2), Offset(2, 0), p);
- canvas.drawLine(Offset(2, 0), Offset(size.width, 0), 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),
@@ -71,13 +79,16 @@ class _RestorePainter extends _IconPainter {
/// Minimize
class MinimizeIcon extends StatelessWidget {
final Color color;
- MinimizeIcon({Key? key, required this.color}) : super(key: key);
+
+ 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);
@@ -89,6 +100,7 @@ class _MinimizePainter extends _IconPainter {
/// Helpers
abstract class _IconPainter extends CustomPainter {
_IconPainter(this.color);
+
final Color color;
@override
@@ -103,7 +115,7 @@ class _AlignedPaint extends StatelessWidget {
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
- child: CustomPaint(size: Size(10, 10), painter: painter));
+ child: CustomPaint(size: const Size(10, 10), painter: painter));
}
}
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/mouse_state_builder.dart b/lib/src/ui/widget/os/mouse_state_builder.dart
similarity index 82%
rename from dependencies/bitsdojo_window-0.1.5/lib/src/widgets/mouse_state_builder.dart
rename to lib/src/ui/widget/os/mouse_state_builder.dart
index 3266758..395951e 100644
--- a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/mouse_state_builder.dart
+++ b/lib/src/ui/widget/os/mouse_state_builder.dart
@@ -6,26 +6,29 @@ typedef MouseStateBuilderCB = Widget Function(
class MouseState {
bool isMouseOver = false;
bool isMouseDown = false;
+
MouseState();
+
@override
String toString() {
- return "isMouseDown: ${this.isMouseDown} - isMouseOver: ${this.isMouseOver}";
+ return "isMouseDown: $isMouseDown - isMouseOver: $isMouseOver";
}
}
-T? _ambiguate(T? value) => value;
-
class MouseStateBuilder extends StatefulWidget {
final MouseStateBuilderCB builder;
final VoidCallback? onPressed;
- MouseStateBuilder({Key? key, required this.builder, this.onPressed})
+
+ const MouseStateBuilder({Key? key, required this.builder, this.onPressed})
: super(key: key);
+
@override
- _MouseStateBuilderState createState() => _MouseStateBuilderState();
+ State createState() => _MouseStateBuilderState();
}
class _MouseStateBuilderState extends State {
late MouseState _mouseState;
+
_MouseStateBuilderState() {
_mouseState = MouseState();
}
@@ -59,7 +62,7 @@ class _MouseStateBuilderState extends State {
_mouseState.isMouseDown = false;
_mouseState.isMouseOver = false;
});
- _ambiguate(WidgetsBinding.instance)!.addPostFrameCallback((_) {
+ WidgetsBinding.instance.addPostFrameCallback((_) {
if (widget.onPressed != null) {
widget.onPressed!();
}
diff --git a/lib/src/ui/widget/os/window_border.dart b/lib/src/ui/widget/os/window_border.dart
index 2fdcbc2..ae90b8b 100644
--- a/lib/src/ui/widget/os/window_border.dart
+++ b/lib/src/ui/widget/os/window_border.dart
@@ -1,4 +1,3 @@
-import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:flutter/material.dart';
import 'package:reboot_launcher/src/util/os.dart';
import 'package:system_theme/system_theme.dart';
@@ -10,18 +9,19 @@ class WindowBorder extends StatelessWidget {
Widget build(BuildContext context) {
return IgnorePointer(
child: Padding(
- padding: EdgeInsets.only(
- top: 1 / appWindow.scaleFactor
+ padding: const EdgeInsets.only(
+ top: 1
),
child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(10),
- border: Border.all(
- color: SystemTheme.accentColor.accent,
- width: appBarSize.toDouble()
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(10),
+ border: Border.all(
+ color: SystemTheme.accentColor.accent,
+ width: appBarSize.toDouble()
+ )
)
- )
),
- ));
+ )
+ );
}
}
diff --git a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_button.dart b/lib/src/ui/widget/os/window_button.dart
similarity index 61%
rename from dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_button.dart
rename to lib/src/ui/widget/os/window_button.dart
index 607c4b9..cfa2b12 100644
--- a/dependencies/bitsdojo_window-0.1.5/lib/src/widgets/window_button.dart
+++ b/lib/src/ui/widget/os/window_button.dart
@@ -1,10 +1,8 @@
import 'package:flutter/material.dart';
+import 'package:window_manager/window_manager.dart';
-import './mouse_state_builder.dart';
-import '../icons/icons.dart';
-import '../app_window.dart';
-import 'package:flutter/foundation.dart' show kIsWeb;
-import 'dart:io' show Platform;
+import 'icons.dart';
+import 'mouse_state_builder.dart';
typedef WindowButtonIconBuilder = Widget Function(
WindowButtonContext buttonContext);
@@ -16,6 +14,7 @@ class WindowButtonContext {
MouseState mouseState;
Color? backgroundColor;
Color iconColor;
+
WindowButtonContext(
{required this.context,
required this.mouseState,
@@ -30,6 +29,7 @@ class WindowButtonColors {
late Color iconNormal;
late Color iconMouseOver;
late Color iconMouseDown;
+
WindowButtonColors(
{Color? normal,
Color? mouseOver,
@@ -48,11 +48,11 @@ class WindowButtonColors {
final _defaultButtonColors = WindowButtonColors(
normal: Colors.transparent,
- iconNormal: Color(0xFF805306),
- mouseOver: Color(0xFF404040),
- mouseDown: Color(0xFF202020),
- iconMouseOver: Color(0xFFFFFFFF),
- iconMouseDown: Color(0xFFF0F0F0));
+ 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;
@@ -88,51 +88,35 @@ class WindowButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
- if (kIsWeb) {
- return Container();
- } else {
- // Don't show button on macOS
- if (Platform.isMacOS) {
- return Container();
- }
- }
- final buttonSize = appWindow.titleBarButtonSize;
return MouseStateBuilder(
- builder: (context, mouseState) {
- WindowButtonContext buttonContext = WindowButtonContext(
- mouseState: mouseState,
- context: context,
- backgroundColor: getBackgroundColor(mouseState),
- iconColor: getIconColor(mouseState));
+ builder: (context, mouseState) {
+ WindowButtonContext buttonContext = WindowButtonContext(
+ mouseState: mouseState,
+ context: context,
+ backgroundColor: getBackgroundColor(mouseState),
+ iconColor: getIconColor(mouseState));
- var icon = (this.iconBuilder != null)
- ? this.iconBuilder!(buttonContext)
- : Container();
- double borderSize = appWindow.borderSize;
- double defaultPadding =
- (appWindow.titleBarHeight - borderSize) / 3 - (borderSize / 2);
- // Used when buttonContext.backgroundColor is null, allowing the AnimatedContainer to fade-out smoothly.
- 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 = (this.builder != null)
- ? this.builder!(buttonContext, icon)
- : iconWithPadding;
- return SizedBox(
- width: 48, height: 48, child: button);
- },
- onPressed: () {
- if (this.onPressed != null) this.onPressed!();
- },
- );
+ 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);
}
}
@@ -148,7 +132,7 @@ class MinimizeWindowButton extends WindowButton {
animate: animate ?? false,
iconBuilder: (buttonContext) =>
MinimizeIcon(color: buttonContext.iconColor),
- onPressed: onPressed ?? () => appWindow.minimize());
+ onPressed: onPressed ?? () => windowManager.minimize());
}
class MaximizeWindowButton extends WindowButton {
@@ -163,7 +147,10 @@ class MaximizeWindowButton extends WindowButton {
animate: animate ?? false,
iconBuilder: (buttonContext) =>
MaximizeIcon(color: buttonContext.iconColor),
- onPressed: onPressed ?? () => appWindow.maximizeOrRestore());
+ onPressed: onPressed ??
+ () async => await windowManager.isMaximized()
+ ? await windowManager.restore()
+ : await windowManager.maximize());
}
class RestoreWindowButton extends WindowButton {
@@ -178,14 +165,17 @@ class RestoreWindowButton extends WindowButton {
animate: animate ?? false,
iconBuilder: (buttonContext) =>
RestoreIcon(color: buttonContext.iconColor),
- onPressed: onPressed ?? () => appWindow.maximizeOrRestore());
+ onPressed: onPressed ??
+ () async => await windowManager.isMaximized()
+ ? await windowManager.restore()
+ : await windowManager.maximize());
}
final _defaultCloseButtonColors = WindowButtonColors(
- mouseOver: Color(0xFFD32F2F),
- mouseDown: Color(0xFFB71C1C),
- iconNormal: Color(0xFF805306),
- iconMouseOver: Color(0xFFFFFFFF));
+ mouseOver: const Color(0xFFD32F2F),
+ mouseDown: const Color(0xFFB71C1C),
+ iconNormal: const Color(0xFF805306),
+ iconMouseOver: const Color(0xFFFFFFFF));
class CloseWindowButton extends WindowButton {
CloseWindowButton(
@@ -199,5 +189,5 @@ class CloseWindowButton extends WindowButton {
animate: animate ?? false,
iconBuilder: (buttonContext) =>
CloseIcon(color: buttonContext.iconColor),
- onPressed: onPressed ?? () => appWindow.close());
+ onPressed: onPressed ?? () => windowManager.close());
}
diff --git a/lib/src/ui/widget/os/window_buttons.dart b/lib/src/ui/widget/os/window_title_bar.dart
similarity index 96%
rename from lib/src/ui/widget/os/window_buttons.dart
rename to lib/src/ui/widget/os/window_title_bar.dart
index 5dce903..156a455 100644
--- a/lib/src/ui/widget/os/window_buttons.dart
+++ b/lib/src/ui/widget/os/window_title_bar.dart
@@ -1,5 +1,5 @@
-import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:fluent_ui/fluent_ui.dart';
+import 'package:reboot_launcher/src/ui/widget/os/window_button.dart';
import 'package:reboot_launcher/src/util/os.dart';
import 'package:system_theme/system_theme.dart';
diff --git a/lib/src/ui/widget/server/server_button.dart b/lib/src/ui/widget/server/server_button.dart
index 2f25a3a..92da23c 100644
--- a/lib/src/ui/widget/server/server_button.dart
+++ b/lib/src/ui/widget/server/server_button.dart
@@ -1,8 +1,8 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
+import 'package:reboot_launcher/src/model/server_type.dart';
import 'package:reboot_launcher/src/ui/controller/server_controller.dart';
import 'package:reboot_launcher/src/ui/dialog/server_dialogs.dart';
-import 'package:reboot_launcher/src/model/server_type.dart';
class ServerButton extends StatefulWidget {
const ServerButton({Key? key}) : super(key: key);
diff --git a/lib/src/ui/widget/server/server_type_selector.dart b/lib/src/ui/widget/server/server_type_selector.dart
index db73d5e..4b536eb 100644
--- a/lib/src/ui/widget/server/server_type_selector.dart
+++ b/lib/src/ui/widget/server/server_type_selector.dart
@@ -1,7 +1,7 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
-import 'package:reboot_launcher/src/ui/controller/server_controller.dart';
import 'package:reboot_launcher/src/model/server_type.dart';
+import 'package:reboot_launcher/src/ui/controller/server_controller.dart';
class ServerTypeSelector extends StatelessWidget {
final ServerController _serverController = Get.find();
diff --git a/lib/src/ui/widget/shared/file_selector.dart b/lib/src/ui/widget/shared/file_selector.dart
index a3eca52..2b3b601 100644
--- a/lib/src/ui/widget/shared/file_selector.dart
+++ b/lib/src/ui/widget/shared/file_selector.dart
@@ -1,11 +1,6 @@
-import 'dart:async';
-
-import 'package:file_picker/file_picker.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/foundation.dart';
-import 'package:get/get.dart';
import 'package:reboot_launcher/src/ui/dialog/snackbar.dart';
-
import 'package:reboot_launcher/src/util/selector.dart';
class FileSelector extends StatefulWidget {
diff --git a/lib/src/ui/widget/shared/fluent_card.dart b/lib/src/ui/widget/shared/fluent_card.dart
deleted file mode 100644
index f49e766..0000000
--- a/lib/src/ui/widget/shared/fluent_card.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'package:fluent_ui/fluent_ui.dart';
-
-class FluentCard extends StatelessWidget {
- final Widget child;
- const FluentCard({Key? key, required this.child}) : super(key: key);
-
- @override
- Widget build(BuildContext context) => Mica(
- elevation: 1,
- child: Card(
- backgroundColor: FluentTheme.of(context).menuColor,
- borderRadius: const BorderRadius.vertical(top: Radius.circular(4.0)),
- child: child
- )
- );
-}
diff --git a/lib/src/ui/widget/shared/profile_widget.dart b/lib/src/ui/widget/shared/profile_widget.dart
new file mode 100644
index 0000000..77f9bd7
--- /dev/null
+++ b/lib/src/ui/widget/shared/profile_widget.dart
@@ -0,0 +1,56 @@
+import 'package:fluent_ui/fluent_ui.dart';
+import 'package:get/get.dart';
+
+import '../../controller/game_controller.dart';
+
+class ProfileWidget extends StatelessWidget {
+ final GameController _gameController = Get.find();
+
+ ProfileWidget({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 12.0,
+ vertical: 12.0
+ ),
+ child: GestureDetector(
+ child: Row(
+ children: [
+ Container(
+ width: 64,
+ height: 64,
+ decoration: const BoxDecoration(
+ shape: BoxShape.circle
+ ),
+ child: Image.asset("assets/images/user.png")
+ ),
+ const SizedBox(
+ width: 12.0,
+ ),
+ const Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "Auties00",
+ textAlign: TextAlign.start,
+ style: TextStyle(
+ fontWeight: FontWeight.w600
+ ),
+ ),
+ Text(
+ "alautiero@gmail.com",
+ textAlign: TextAlign.start,
+ style: TextStyle(
+ fontWeight: FontWeight.w100
+ ),
+ )
+ ],
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/src/util/build.dart b/lib/src/util/build.dart
index f654e10..097238e 100644
--- a/lib/src/util/build.dart
+++ b/lib/src/util/build.dart
@@ -2,13 +2,12 @@ import 'dart:async';
import 'dart:io';
import 'dart:isolate';
-import 'package:archive/archive_io.dart';
import 'package:html/parser.dart' show parse;
import 'package:http/http.dart' as http;
+import 'package:path/path.dart' as path;
import 'package:reboot_launcher/src/model/fortnite_build.dart';
import 'package:reboot_launcher/src/util/time.dart';
import 'package:reboot_launcher/src/util/version.dart' as parser;
-import 'package:path/path.dart' as path;
import 'os.dart';
diff --git a/lib/src/util/checks.dart b/lib/src/util/checks.dart
index b1de1ee..02d7259 100644
--- a/lib/src/util/checks.dart
+++ b/lib/src/util/checks.dart
@@ -1,9 +1,6 @@
-import 'dart:async';
import 'dart:io';
-import 'package:reboot_launcher/src/util/server.dart';
-
-import '../model/fortnite_version.dart';
+import 'package:reboot_launcher/src/model/fortnite_version.dart';
String? checkVersion(String? text, List versions) {
if (text == null || text.isEmpty) {
diff --git a/lib/src/util/error.dart b/lib/src/util/error.dart
index 377242c..e146f77 100644
--- a/lib/src/util/error.dart
+++ b/lib/src/util/error.dart
@@ -1,7 +1,7 @@
import 'package:fluent_ui/fluent_ui.dart';
-import '../../../main.dart';
-import '../ui/dialog/dialog.dart';
+import 'package:reboot_launcher/main.dart';
+import 'package:reboot_launcher/src/ui/dialog/dialog.dart';
String? lastError;
diff --git a/lib/src/util/injector.dart b/lib/src/util/injector.dart
index f0cfa84..552e739 100644
--- a/lib/src/util/injector.dart
+++ b/lib/src/util/injector.dart
@@ -2,8 +2,8 @@
import 'dart:ffi';
-import 'package:win32/win32.dart';
import 'package:ffi/ffi.dart';
+import 'package:win32/win32.dart';
final _kernel32 = DynamicLibrary.open('kernel32.dll');
final _CreateRemoteThread = _kernel32.lookupFunction<
diff --git a/lib/src/util/os.dart b/lib/src/util/os.dart
index 30201b8..6945269 100644
--- a/lib/src/util/os.dart
+++ b/lib/src/util/os.dart
@@ -1,8 +1,8 @@
+import 'dart:ffi';
import 'dart:io';
-import 'package:win32/win32.dart';
import 'package:ffi/ffi.dart';
-import 'dart:ffi';
+import 'package:win32/win32.dart';
const int appBarSize = 2;
diff --git a/lib/src/util/process.dart b/lib/src/util/process.dart
index 4f8e246..59c7b93 100644
--- a/lib/src/util/process.dart
+++ b/lib/src/util/process.dart
@@ -1,6 +1,5 @@
import 'dart:ffi';
-import 'package:win32/src/kernel32.dart';
import 'package:win32/win32.dart';
final _ntdll = DynamicLibrary.open('ntdll.dll');
diff --git a/lib/src/util/server.dart b/lib/src/util/server.dart
index 2ca1048..5d0e89c 100644
--- a/lib/src/util/server.dart
+++ b/lib/src/util/server.dart
@@ -2,15 +2,14 @@ import 'dart:convert';
import 'dart:io';
import 'dart:math';
+import 'package:http/http.dart' as http;
import 'package:ini/ini.dart';
import 'package:process_run/shell.dart';
import 'package:reboot_launcher/src/model/server_type.dart';
import 'package:reboot_launcher/src/ui/controller/game_controller.dart';
import 'package:reboot_launcher/src/util/os.dart';
-import 'package:shelf_proxy/shelf_proxy.dart';
import 'package:shelf/shelf_io.dart';
-
-import 'package:http/http.dart' as http;
+import 'package:shelf_proxy/shelf_proxy.dart';
final serverLogFile = File("${logsDirectory.path}\\server.log");
final serverDirectory = Directory("${assetsDirectory.path}\\lawin");
diff --git a/pubspec.yaml b/pubspec.yaml
index 30c6511..ae24dfe 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -11,9 +11,7 @@ dependencies:
flutter:
sdk: flutter
- bitsdojo_window:
- path: ./dependencies/bitsdojo_window-0.1.5
- fluent_ui: ^4.6.2
+ fluent_ui: ^4.7.3
bitsdojo_window_windows: ^0.1.5
system_theme: ^2.0.0
http: ^0.13.5
@@ -43,6 +41,7 @@ dependencies:
supabase_flutter: ^1.10.0
supabase: ^1.9.1
fluentui_system_icons: ^1.1.202
+ flutter_acrylic: ^1.1.3
dev_dependencies:
flutter_test:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index ae6c766..0418bb6 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
#include
@@ -18,6 +19,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
BitsdojoWindowPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
+ FlutterAcrylicPluginRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("FlutterAcrylicPlugin"));
ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
SystemThemePluginRegisterWithRegistrar(
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index b1095ae..65e1e6c 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -5,6 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
app_links
bitsdojo_window_windows
+ flutter_acrylic
screen_retriever
system_theme
url_launcher_windows
diff --git a/windows/packaging/exe/custom-inno-setup-script.iss b/windows/packaging/exe/custom-inno-setup-script.iss
new file mode 100644
index 0000000..a974572
--- /dev/null
+++ b/windows/packaging/exe/custom-inno-setup-script.iss
@@ -0,0 +1,36 @@
+[Setup]
+AppId={{APP_ID}}
+AppVersion={{APP_VERSION}}
+AppName={{DISPLAY_NAME}}
+AppPublisher={{PUBLISHER_NAME}}
+AppPublisherURL={{PUBLISHER_URL}}
+AppSupportURL={{PUBLISHER_URL}}
+AppUpdatesURL={{PUBLISHER_URL}}
+DefaultDirName={{INSTALL_DIR_NAME}}
+DisableProgramGroupPage=yes
+OutputBaseFilename={{OUTPUT_BASE_FILENAME}}
+Compression=lzma
+SolidCompression=yes
+SetupIconFile={{SETUP_ICON_FILE}}
+WizardStyle=modern
+PrivilegesRequired=admin
+ArchitecturesAllowed=x64
+ArchitecturesInstallIn64BitMode=x64
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce
+Name: "launchAtStartup"; Description: "{cm:AutoStartProgram,{{DISPLAY_NAME}}}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "reboot_launcher-8.1.0+8.1.0-windows-setup_exe\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+
+[Run]
+Filename: "{app}\\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: runascurrentuser nowait postinstall skipifsilent
+
+[Icons]
+Name: "{autoprograms}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"
+Name: "{autodesktop}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; Tasks: desktopicon
+Name: "{userstartup}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup
diff --git a/windows/packaging/exe/make_config.yaml b/windows/packaging/exe/make_config.yaml
index 69687f3..7e38c5a 100644
--- a/windows/packaging/exe/make_config.yaml
+++ b/windows/packaging/exe/make_config.yaml
@@ -1,6 +1,9 @@
+script_template: "custom-inno-setup-script.iss"
app_id: 31868Auties00.RebootLauncher
publisher_name: Auties00
+publisher_url: https://github.com/Auties00
display_name: Reboot Launcher
+install_dir_name: Reboot Launcher
create_desktop_icon: true
locales:
- en
\ No newline at end of file
diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp
index 5c2ec15..d39742d 100644
--- a/windows/runner/main.cpp
+++ b/windows/runner/main.cpp
@@ -1,5 +1,5 @@
#include
-auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP);
+auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME);
#include
@@ -15,19 +15,20 @@ auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP);
#include
#include
-bool CheckOneInstance()
-{
- HANDLE m_hStartEvent = CreateEventW( NULL, FALSE, FALSE, L"reboot_launcher");
- if(m_hStartEvent == NULL)
- {
- CloseHandle( m_hStartEvent );
+bool CheckOneInstance(){
+ HANDLE hMutex = CreateMutexW(NULL, TRUE, L"RebootLauncherMutex");
+ if (hMutex == NULL) {
return false;
}
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- CloseHandle( m_hStartEvent );
- m_hStartEvent = NULL;
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ HWND hwndExisting = FindWindowW(NULL, L"Reboot Launcher");
+ if (hwndExisting != NULL) {
+ ShowWindow(hwndExisting, SW_RESTORE);
+ SetForegroundWindow(hwndExisting);
+ }
+
+ CloseHandle(hMutex);
return false;
}
@@ -58,7 +59,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
- if (!window.CreateAndShow(L"reboot_launcher", origin, size)) {
+ if (!window.CreateAndShow(L"Reboot Launcher", origin, size)) {
return EXIT_FAILURE;
}
diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp
index c10f08d..47e2ff0 100644
--- a/windows/runner/win32_window.cpp
+++ b/windows/runner/win32_window.cpp
@@ -4,6 +4,8 @@
#include "resource.h"
+#include
+
namespace {
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
@@ -108,7 +110,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
Destroy();
const wchar_t* window_class =
- WindowClassRegistrar::GetInstance()->GetWindowClass();
+ WindowClassRegistrar::GetInstance()->GetWindowClass();
const POINT target_point = {static_cast(origin.x),
static_cast(origin.y)};
@@ -117,10 +119,18 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0;
HWND window = CreateWindow(
- window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
- Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
- Scale(size.width, scale_factor), Scale(size.height, scale_factor),
- nullptr, nullptr, GetModuleHandle(nullptr), this);
+ window_class,
+ title.c_str(),
+ WS_OVERLAPPED & ~WS_VISIBLE,
+ Scale(origin.x, scale_factor),
+ Scale(origin.y, scale_factor),
+ Scale(size.width, scale_factor),
+ Scale(size.height, scale_factor),
+ nullptr,
+ nullptr,
+ GetModuleHandle(nullptr),
+ this
+ );
if (!window) {
return false;