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