mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 03:02:22 +01:00
Added remote lawin server
This commit is contained in:
@@ -9,10 +9,10 @@ import 'package:get_storage/get_storage.dart';
|
|||||||
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/page/home_page.dart';
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
import 'package:reboot_launcher/src/util/os.dart';
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
import 'package:system_theme/system_theme.dart';
|
import 'package:system_theme/system_theme.dart';
|
||||||
import 'package:reboot_launcher/src/page/home_page.dart';
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await Directory(safeBinariesDirectory)
|
await Directory(safeBinariesDirectory)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
||||||
|
|
||||||
class BuildController extends GetxController {
|
class BuildController extends GetxController {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'dart:io';
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get_storage/get_storage.dart';
|
import 'package:get_storage/get_storage.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
||||||
|
|
||||||
class GameController extends GetxController {
|
class GameController extends GetxController {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'dart:io';
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get_storage/get_storage.dart';
|
import 'package:get_storage/get_storage.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
import 'package:reboot_launcher/src/util/server.dart';
|
import 'package:reboot_launcher/src/util/server.dart';
|
||||||
|
|
||||||
@@ -13,6 +12,7 @@ class ServerController extends GetxController {
|
|||||||
late final RxBool embedded;
|
late final RxBool embedded;
|
||||||
late final RxBool warning;
|
late final RxBool warning;
|
||||||
late RxBool started;
|
late RxBool started;
|
||||||
|
HttpServer? reverseProxy;
|
||||||
|
|
||||||
ServerController() {
|
ServerController() {
|
||||||
var storage = GetStorage("server");
|
var storage = GetStorage("server");
|
||||||
@@ -23,18 +23,30 @@ class ServerController extends GetxController {
|
|||||||
port.addListener(() => storage.write("port", port.text));
|
port.addListener(() => storage.write("port", port.text));
|
||||||
|
|
||||||
embedded = RxBool(storage.read("embedded") ?? true);
|
embedded = RxBool(storage.read("embedded") ?? true);
|
||||||
embedded.listen((value) => storage.write("embedded", value));
|
embedded.listen((value) {
|
||||||
|
storage.write("embedded", value);
|
||||||
|
|
||||||
|
if(!started.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(value){
|
||||||
|
reverseProxy?.close(force: true);
|
||||||
|
reverseProxy = null;
|
||||||
|
started(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadBinary("release.bat", false)
|
||||||
|
.then((value) => Process.run(value.path, []))
|
||||||
|
.then((value) => started(false));
|
||||||
|
});
|
||||||
|
|
||||||
warning = RxBool(storage.read("lawin_value") ?? true);
|
warning = RxBool(storage.read("lawin_value") ?? true);
|
||||||
warning.listen((value) => storage.write("lawin_value", value));
|
warning.listen((value) => storage.write("lawin_value", value));
|
||||||
|
|
||||||
started = RxBool(false);
|
started = RxBool(false);
|
||||||
isLawinPortFree()
|
isLawinPortFree()
|
||||||
.then((value) => started = RxBool(!value));
|
.then((value) => !embedded.value ? {} : started = RxBool(!value));
|
||||||
}
|
|
||||||
|
|
||||||
Future kill() async {
|
|
||||||
var release = await loadBinary("release.bat", false);
|
|
||||||
return Process.run(release.path, []);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import 'package:get_storage/get_storage.dart';
|
|||||||
import 'package:reboot_launcher/src/page/info_page.dart';
|
import 'package:reboot_launcher/src/page/info_page.dart';
|
||||||
import 'package:reboot_launcher/src/page/launcher_page.dart';
|
import 'package:reboot_launcher/src/page/launcher_page.dart';
|
||||||
import 'package:reboot_launcher/src/page/server_page.dart';
|
import 'package:reboot_launcher/src/page/server_page.dart';
|
||||||
import 'package:reboot_launcher/src/widget/window_buttons.dart';
|
|
||||||
import 'package:reboot_launcher/src/widget/window_border.dart';
|
|
||||||
import 'package:window_manager/window_manager.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/util/os.dart';
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/window_border.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/window_buttons.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
import '../util/reboot.dart';
|
import '../util/reboot.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
||||||
import 'package:reboot_launcher/src/util/os.dart';
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
import 'package:reboot_launcher/src/widget/deployment_selector.dart';
|
import 'package:reboot_launcher/src/widget/deployment_selector.dart';
|
||||||
import 'package:reboot_launcher/src/widget/launch_button.dart';
|
import 'package:reboot_launcher/src/widget/launch_button.dart';
|
||||||
import 'package:reboot_launcher/src/widget/username_box.dart';
|
import 'package:reboot_launcher/src/widget/username_box.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/widget/version_selector.dart';
|
import 'package:reboot_launcher/src/widget/version_selector.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
import 'package:reboot_launcher/src/widget/warning_info.dart';
|
import 'package:reboot_launcher/src/widget/host_input.dart';
|
||||||
import 'package:reboot_launcher/src/widget/local_server_switch.dart';
|
import 'package:reboot_launcher/src/widget/local_server_switch.dart';
|
||||||
import 'package:reboot_launcher/src/widget/port_input.dart';
|
import 'package:reboot_launcher/src/widget/port_input.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/widget/host_input.dart';
|
|
||||||
import 'package:reboot_launcher/src/widget/server_button.dart';
|
import 'package:reboot_launcher/src/widget/server_button.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/warning_info.dart';
|
||||||
|
|
||||||
class ServerPage extends StatelessWidget {
|
class ServerPage extends StatelessWidget {
|
||||||
final ServerController _serverController = Get.find<ServerController>();
|
final ServerController _serverController = Get.find<ServerController>();
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:path/path.dart' as path;
|
|
||||||
import 'package:reboot_launcher/src/util/version.dart' as parser;
|
|
||||||
import 'package:html/parser.dart' show parse;
|
import 'package:html/parser.dart' show parse;
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
|
||||||
|
|
||||||
import 'package:process_run/shell.dart';
|
import 'package:process_run/shell.dart';
|
||||||
|
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/version.dart' as parser;
|
||||||
|
|
||||||
const _userAgent =
|
const _userAgent =
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36";
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36";
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:archive/archive_io.dart';
|
import 'package:archive/archive_io.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:crypto/crypto.dart';
|
import 'package:crypto/crypto.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
|
|
||||||
const _rebootUrl =
|
const _rebootUrl =
|
||||||
"https://nightly.link/Milxnor/Universal-Walking-Simulator/workflows/msbuild/master/Release.zip";
|
"https://nightly.link/Milxnor/Universal-Walking-Simulator/workflows/msbuild/master/Release.zip";
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:archive/archive_io.dart';
|
import 'package:archive/archive_io.dart';
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:process_run/shell.dart';
|
import 'package:process_run/shell.dart';
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
|
import 'package:shelf/shelf_io.dart' as shelf_io;
|
||||||
|
import 'package:shelf_proxy/shelf_proxy.dart';
|
||||||
|
|
||||||
final serverLocation = Directory("${Platform.environment["UserProfile"]}/.reboot_launcher/lawin");
|
final serverLocation = Directory("${Platform.environment["UserProfile"]}/.reboot_launcher/lawin");
|
||||||
const String _serverUrl =
|
const String _serverUrl =
|
||||||
@@ -47,27 +47,76 @@ Future<bool> isLawinPortFree() async {
|
|||||||
return !process.outText.contains(" LISTENING "); // Goofy way, best we got
|
return !process.outText.contains(" LISTENING "); // Goofy way, best we got
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> showRemoteServerCheck(BuildContext context, String host, String port, [bool autoClose = false]) async {
|
Future<HttpServer?> changeReverseProxyState(BuildContext context, String host, String port, HttpServer? server) async {
|
||||||
var future = _pingServer(host, port).then((value) {
|
if(server != null){
|
||||||
if(value && autoClose){
|
try{
|
||||||
Navigator.of(context).pop();
|
server.close(force: true);
|
||||||
|
return null;
|
||||||
|
}catch(error){
|
||||||
|
_showStopProxyError(context, error);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
host = host.trim();
|
||||||
});
|
if(host.isEmpty){
|
||||||
await showDialog(
|
showSnackbar(
|
||||||
|
context, const Snackbar(content: Text("Missing host name")));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = port.trim();
|
||||||
|
if(port.isEmpty){
|
||||||
|
showSnackbar(
|
||||||
|
context, const Snackbar(content: Text("Missing port", textAlign: TextAlign.center)));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(int.tryParse(port) == null){
|
||||||
|
showSnackbar(
|
||||||
|
context, const Snackbar(content: Text("Invalid port, use only numbers", textAlign: TextAlign.center)));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
var uri = await _showReverseProxyCheck(context, host, port);
|
||||||
|
if(uri == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await shelf_io.serve(proxyHandler(uri), 'localhost', 3551);
|
||||||
|
}catch(error){
|
||||||
|
_showStartProxyError(context, error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Uri?> _showReverseProxyCheck(BuildContext context, String host, String port) async {
|
||||||
|
var future = _pingServer(host, port);
|
||||||
|
return await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => ContentDialog(
|
builder: (context) => ContentDialog(
|
||||||
content: FutureBuilder<bool>(
|
content: FutureBuilder<Uri?>(
|
||||||
future: future,
|
future: future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if(snapshot.hasData){
|
if(snapshot.hasError){
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Text(snapshot.data! ? "The server answered correctly" : "The remote server doesn't work correctly or the IP and/or the port are incorrect" , textAlign: TextAlign.center)
|
child: Text("Cannot ping remote server: ${snapshot.error}" , textAlign: TextAlign.center)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(snapshot.connectionState == ConnectionState.done && !snapshot.hasData){
|
||||||
|
return const SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Text("The remote server doesn't work correctly or the IP and/or the port are incorrect" , textAlign: TextAlign.center)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(snapshot.hasData){
|
||||||
|
Navigator.of(context).pop(snapshot.data);
|
||||||
|
}
|
||||||
|
|
||||||
return const InfoLabel(
|
return const InfoLabel(
|
||||||
label: "Pinging remote lawin server...",
|
label: "Pinging remote lawin server...",
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@@ -86,30 +135,81 @@ Future<bool> showRemoteServerCheck(BuildContext context, String host, String por
|
|||||||
backgroundColor: ButtonState.all(Colors.red)),
|
backgroundColor: ButtonState.all(Colors.red)),
|
||||||
child: const Text('Close'),
|
child: const Text('Close'),
|
||||||
))
|
))
|
||||||
],
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return await future;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _pingServer(String host, String port, [bool https=false]) async {
|
Future<Uri?> _pingServer(String host, String port, [bool https=false]) async {
|
||||||
|
var hostName = _getHostName(host);
|
||||||
|
var declaredScheme = _getScheme(host);
|
||||||
try{
|
try{
|
||||||
var uri = Uri(
|
var uri = Uri(
|
||||||
scheme: https ? "https" : "http",
|
scheme: declaredScheme ?? (https ? "https" : "http"),
|
||||||
host: host,
|
host: hostName,
|
||||||
port: int.parse(port)
|
port: int.parse(port)
|
||||||
);
|
);
|
||||||
var client = HttpClient()
|
var client = HttpClient()
|
||||||
..connectionTimeout = const Duration(seconds: 5);
|
..connectionTimeout = const Duration(seconds: 5);
|
||||||
var request = await client.getUrl(uri);
|
var request = await client.getUrl(uri);
|
||||||
var response = await request.close();
|
var response = await request.close();
|
||||||
return response.statusCode == 200;
|
return response.statusCode == 200 ? uri : null;
|
||||||
}catch(_){
|
}catch(_){
|
||||||
return https ? false : await _pingServer(host, port, true);
|
return https || declaredScheme != null ? null : await _pingServer(host, port, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? _getHostName(String host) => host.replaceFirst("http://", "").replaceFirst("https://", "");
|
||||||
|
|
||||||
|
String? _getScheme(String host) => host.startsWith("http://") ? "http" : host.startsWith("https://") ? "https" : null;
|
||||||
|
|
||||||
|
|
||||||
|
void _showStartProxyError(BuildContext context, Object error) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => ContentDialog(
|
||||||
|
content: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Text("Cannot create the reverse proxy: $error", textAlign: TextAlign.center)
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: FilledButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: ButtonState.all(Colors.red)),
|
||||||
|
child: const Text('Close'),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showStopProxyError(BuildContext context, Object error) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => ContentDialog(
|
||||||
|
content: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Text("Cannot kill the reverse proxy: $error", textAlign: TextAlign.center)
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: FilledButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: ButtonState.all(Colors.red)),
|
||||||
|
child: const Text('Close'),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> changeEmbeddedServerState(BuildContext context, bool running) async {
|
Future<bool> changeEmbeddedServerState(BuildContext context, bool running) async {
|
||||||
if (running) {
|
if (running) {
|
||||||
var releaseBat = await loadBinary("release.bat", false);
|
var releaseBat = await loadBinary("release.bat", false);
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ import 'dart:io';
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/widget/select_file.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/select_file.dart';
|
||||||
|
|
||||||
class AddLocalVersion extends StatelessWidget {
|
class AddLocalVersion extends StatelessWidget {
|
||||||
final GameController _gameController = Get.find<GameController>();
|
final GameController _gameController = Get.find<GameController>();
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:async/async.dart';
|
import 'package:async/async.dart';
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:process_run/shell.dart';
|
|
||||||
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/util/build.dart';
|
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/build.dart';
|
||||||
import 'package:reboot_launcher/src/widget/select_file.dart';
|
import 'package:reboot_launcher/src/widget/select_file.dart';
|
||||||
import 'package:reboot_launcher/src/widget/version_name_input.dart';
|
import 'package:reboot_launcher/src/widget/version_name_input.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
|
||||||
import 'build_selector.dart';
|
import 'build_selector.dart';
|
||||||
|
|
||||||
class AddServerVersion extends StatefulWidget {
|
class AddServerVersion extends StatefulWidget {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
import 'package:reboot_launcher/src/controller/build_controller.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
import 'package:reboot_launcher/src/model/fortnite_build.dart';
|
||||||
|
|
||||||
class BuildSelector extends StatefulWidget {
|
class BuildSelector extends StatefulWidget {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/widget/smart_switch.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/smart_switch.dart';
|
||||||
|
|
||||||
class DeploymentSelector extends StatelessWidget {
|
class DeploymentSelector extends StatelessWidget {
|
||||||
final GameController _gameController = Get.find<GameController>();
|
final GameController _gameController = Get.find<GameController>();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/widget/smart_input.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/smart_input.dart';
|
||||||
|
|
||||||
class HostInput extends StatelessWidget {
|
class HostInput extends StatelessWidget {
|
||||||
final ServerController _serverController = Get.find<ServerController>();
|
final ServerController _serverController = Get.find<ServerController>();
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ import 'package:get/get.dart';
|
|||||||
import 'package:process_run/shell.dart';
|
import 'package:process_run/shell.dart';
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
import 'package:reboot_launcher/src/util/injector.dart';
|
|
||||||
import 'package:reboot_launcher/src/util/binary.dart';
|
import 'package:reboot_launcher/src/util/binary.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/injector.dart';
|
||||||
import 'package:reboot_launcher/src/util/patcher.dart';
|
import 'package:reboot_launcher/src/util/patcher.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/server.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:win32_suspend_process/win32_suspend_process.dart';
|
import 'package:win32_suspend_process/win32_suspend_process.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/util/server.dart';
|
|
||||||
|
|
||||||
class LaunchButton extends StatefulWidget {
|
class LaunchButton extends StatefulWidget {
|
||||||
const LaunchButton(
|
const LaunchButton(
|
||||||
{Key? key})
|
{Key? key})
|
||||||
@@ -65,28 +64,6 @@ class _LaunchButtonState extends State<LaunchButton> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_serverController.embedded.value && !_serverController.started.value && await isLawinPortFree()) {
|
|
||||||
if(!mounted){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = await changeEmbeddedServerState(context, false);
|
|
||||||
_serverController.started(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateServerState(true);
|
|
||||||
_onStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _updateServerState(bool value) async {
|
|
||||||
if (_gameController.started.value == value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameController.started(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onStart() async {
|
|
||||||
try {
|
try {
|
||||||
_updateServerState(true);
|
_updateServerState(true);
|
||||||
var version = _gameController.selectedVersionObs.value!;
|
var version = _gameController.selectedVersionObs.value!;
|
||||||
@@ -101,17 +78,16 @@ class _LaunchButtonState extends State<LaunchButton> {
|
|||||||
Win32Process(_gameController.eacProcess!.pid).suspend();
|
Win32Process(_gameController.eacProcess!.pid).suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_serverController.embedded.value){
|
|
||||||
var available = await _showPingWarning();
|
|
||||||
if(!available) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hosting){
|
if(hosting){
|
||||||
await patchExe(version.executable!);
|
await patchExe(version.executable!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await _startServerIfNecessary();
|
||||||
|
if(!_serverController.started.value){
|
||||||
|
_onStop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_gameController.gameProcess = await Process.start(version.executable!.path, _createProcessArguments())
|
_gameController.gameProcess = await Process.start(version.executable!.path, _createProcessArguments())
|
||||||
..exitCode.then((_) => _onEnd())
|
..exitCode.then((_) => _onEnd())
|
||||||
..outLines.forEach(_onGameOutput);
|
..outLines.forEach(_onGameOutput);
|
||||||
@@ -126,6 +102,43 @@ class _LaunchButtonState extends State<LaunchButton> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _startServerIfNecessary() async {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_serverController.started.value){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(await isLawinPortFree())){
|
||||||
|
_serverController.started(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_serverController.embedded.value) {
|
||||||
|
var result = await changeEmbeddedServerState(context, false);
|
||||||
|
_serverController.started(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_serverController.reverseProxy = await changeReverseProxyState(
|
||||||
|
context,
|
||||||
|
_serverController.host.text,
|
||||||
|
_serverController.port.text,
|
||||||
|
_serverController.reverseProxy
|
||||||
|
);
|
||||||
|
_serverController.started(_serverController.reverseProxy != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _updateServerState(bool value) async {
|
||||||
|
if (_gameController.started.value == value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gameController.started(value);
|
||||||
|
}
|
||||||
|
|
||||||
void _onEnd() {
|
void _onEnd() {
|
||||||
if(_lawinFail){
|
if(_lawinFail){
|
||||||
return;
|
return;
|
||||||
@@ -148,19 +161,6 @@ class _LaunchButtonState extends State<LaunchButton> {
|
|||||||
Navigator.of(context).pop(false);
|
Navigator.of(context).pop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _showPingWarning() async {
|
|
||||||
if(!mounted){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await showRemoteServerCheck(
|
|
||||||
context,
|
|
||||||
_serverController.host.text,
|
|
||||||
_serverController.port.text,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _showBrokenServerWarning() async {
|
Future<void> _showBrokenServerWarning() async {
|
||||||
if(!mounted){
|
if(!mounted){
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/widget/smart_switch.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/smart_switch.dart';
|
||||||
|
|
||||||
class LocalServerSwitch extends StatelessWidget {
|
class LocalServerSwitch extends StatelessWidget {
|
||||||
final ServerController _serverController = Get.find<ServerController>();
|
final ServerController _serverController = Get.find<ServerController>();
|
||||||
@@ -15,7 +14,7 @@ class LocalServerSwitch extends StatelessWidget {
|
|||||||
message: "Determines whether an embedded or remote lawin server should be used",
|
message: "Determines whether an embedded or remote lawin server should be used",
|
||||||
child: SmartSwitch(
|
child: SmartSwitch(
|
||||||
value: _serverController.embedded,
|
value: _serverController.embedded,
|
||||||
label: "Embedded"
|
label: "Embedded",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/widget/smart_input.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/smart_input.dart';
|
||||||
|
|
||||||
class PortInput extends StatelessWidget {
|
class PortInput extends StatelessWidget {
|
||||||
final ServerController _serverController = Get.find<ServerController>();
|
final ServerController _serverController = Get.find<ServerController>();
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:reboot_launcher/src/util/os.dart';
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
import 'package:reboot_launcher/src/widget/select_file.dart';
|
import 'package:reboot_launcher/src/widget/select_file.dart';
|
||||||
import 'package:path/path.dart' as path;
|
|
||||||
|
|
||||||
|
|
||||||
class ScanLocalVersion extends StatefulWidget {
|
class ScanLocalVersion extends StatefulWidget {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/util/server.dart';
|
import 'package:reboot_launcher/src/util/server.dart';
|
||||||
|
|
||||||
class ServerButton extends StatelessWidget {
|
class ServerButton extends StatelessWidget {
|
||||||
@@ -16,35 +15,56 @@ class ServerButton extends StatelessWidget {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Obx(() => Tooltip(
|
child: Obx(() => Tooltip(
|
||||||
message: !_serverController.embedded.value
|
message: _helpMessage,
|
||||||
? "Check the address of the remote Lawin server"
|
|
||||||
: _serverController.started.value
|
|
||||||
? "Stop the running Lawin server instance"
|
|
||||||
: "Start a new Lawin server instance",
|
|
||||||
child: Button(
|
child: Button(
|
||||||
onPressed: () => _onPressed(context),
|
onPressed: () => _onPressed(context),
|
||||||
child: Text(_serverController.embedded.value
|
child: Text(!_serverController.started.value
|
||||||
? !_serverController.started.value
|
|
||||||
? "Start"
|
? "Start"
|
||||||
: "Stop"
|
: "Stop")),
|
||||||
: "Ping Server")),
|
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get _helpMessage {
|
||||||
|
if (_serverController.embedded.value) {
|
||||||
|
if (_serverController.started.value) {
|
||||||
|
return "Stop the Lawin server currently running";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Start a new local Lawin server";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_serverController.started.value) {
|
||||||
|
return "Stop the reverse proxy currently running";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Start a reverse proxy targeting the remote Lawin server";
|
||||||
|
}
|
||||||
|
|
||||||
void _onPressed(BuildContext context) async {
|
void _onPressed(BuildContext context) async {
|
||||||
|
var running = _serverController.started.value;
|
||||||
|
_serverController.started.value = !running;
|
||||||
if (!_serverController.embedded.value) {
|
if (!_serverController.embedded.value) {
|
||||||
showRemoteServerCheck(
|
_serverController.reverseProxy = await changeReverseProxyState(
|
||||||
context, _serverController.host.text, _serverController.port.text);
|
context,
|
||||||
|
_serverController.host.text,
|
||||||
|
_serverController.port.text,
|
||||||
|
_serverController.reverseProxy
|
||||||
|
);
|
||||||
|
_updateStarted(_serverController.reverseProxy != null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var running = _serverController.started.value;
|
|
||||||
_serverController.started.value = !running;
|
|
||||||
var updatedRunning = await changeEmbeddedServerState(context, running);
|
var updatedRunning = await changeEmbeddedServerState(context, running);
|
||||||
if (updatedRunning != _serverController.started.value) {
|
_updateStarted(updatedRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateStarted(bool updatedRunning) {
|
||||||
|
if (updatedRunning == _serverController.started.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_serverController.started.value = updatedRunning;
|
_serverController.started.value = updatedRunning;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:reboot_launcher/src/widget/smart_input.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/widget/smart_input.dart';
|
||||||
|
|
||||||
class UsernameBox extends StatelessWidget {
|
class UsernameBox extends StatelessWidget {
|
||||||
final GameController _gameController = Get.find<GameController>();
|
final GameController _gameController = Get.find<GameController>();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
|
|
||||||
class VersionNameInput extends StatelessWidget {
|
class VersionNameInput extends StatelessWidget {
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart'
|
import 'package:flutter/material.dart'
|
||||||
show showMenu, PopupMenuEntry, PopupMenuItem;
|
show showMenu, PopupMenuEntry, PopupMenuItem;
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
||||||
import 'package:reboot_launcher/src/widget/add_local_version.dart';
|
import 'package:reboot_launcher/src/widget/add_local_version.dart';
|
||||||
import 'package:reboot_launcher/src/widget/add_server_version.dart';
|
import 'package:reboot_launcher/src/widget/add_server_version.dart';
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/model/fortnite_version.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
|
||||||
import 'package:reboot_launcher/src/widget/scan_local_version.dart';
|
import 'package:reboot_launcher/src/widget/scan_local_version.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import '../controller/build_controller.dart';
|
class VersionSelector extends StatefulWidget {
|
||||||
|
|
||||||
class VersionSelector extends StatelessWidget {
|
|
||||||
final GameController _gameController = Get.find<GameController>();
|
|
||||||
final bool enableScanner;
|
final bool enableScanner;
|
||||||
|
|
||||||
VersionSelector({Key? key, this.enableScanner = false}) : super(key: key);
|
const VersionSelector({Key? key, this.enableScanner = false}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<VersionSelector> createState() => _VersionSelectorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VersionSelectorState extends State<VersionSelector> {
|
||||||
|
final GameController _gameController = Get.find<GameController>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -46,14 +45,14 @@ class VersionSelector extends StatelessWidget {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
),
|
),
|
||||||
if(enableScanner)
|
if(widget.enableScanner)
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: "Scan all fortnite builds in a directory",
|
message: "Scan all fortnite builds in a directory",
|
||||||
child: Button(
|
child: Button(
|
||||||
child: const Icon(FluentIcons.site_scan),
|
child: const Icon(FluentIcons.site_scan),
|
||||||
onPressed: () => _openScanLocalVersionDialog(context)),
|
onPressed: () => _openScanLocalVersionDialog(context)),
|
||||||
),
|
),
|
||||||
if(enableScanner)
|
if(widget.enableScanner)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
),
|
),
|
||||||
@@ -125,7 +124,7 @@ class VersionSelector extends StatelessWidget {
|
|||||||
void _openScanLocalVersionDialog(BuildContext context) async {
|
void _openScanLocalVersionDialog(BuildContext context) async {
|
||||||
await showDialog<bool>(
|
await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => ScanLocalVersion());
|
builder: (context) => const ScanLocalVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _openMenu(
|
Future<void> _openMenu(
|
||||||
@@ -142,13 +141,26 @@ class VersionSelector extends StatelessWidget {
|
|||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case 0:
|
case 0:
|
||||||
|
if(!mounted){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
launchUrl(version.location.uri);
|
launchUrl(version.location.uri);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
_gameController.removeVersion(version);
|
_gameController.removeVersion(version);
|
||||||
|
|
||||||
|
if(!mounted){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await _openDeleteDialog(context, version);
|
await _openDeleteDialog(context, version);
|
||||||
|
if(!mounted){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
if (_gameController.selectedVersionObs.value?.name == version.name || _gameController.hasNoVersions) {
|
if (_gameController.selectedVersionObs.value?.name == version.name || _gameController.hasNoVersions) {
|
||||||
_gameController.selectedVersionObs.value = null;
|
_gameController.selectedVersionObs.value = null;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:system_theme/system_theme.dart';
|
|
||||||
|
|
||||||
import 'package:reboot_launcher/src/util/os.dart';
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
|
import 'package:system_theme/system_theme.dart';
|
||||||
|
|
||||||
class WindowBorder extends StatelessWidget {
|
class WindowBorder extends StatelessWidget {
|
||||||
const WindowBorder({Key? key}) : super(key: key);
|
const WindowBorder({Key? key}) : super(key: key);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:reboot_launcher/src/util/os.dart';
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ dependencies:
|
|||||||
get: ^4.6.5
|
get: ^4.6.5
|
||||||
get_storage: ^2.0.3
|
get_storage: ^2.0.3
|
||||||
window_manager: ^0.2.7
|
window_manager: ^0.2.7
|
||||||
|
shelf_proxy: ^1.0.2
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
win32: ^3.0.0
|
win32: ^3.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user