mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 03:02:22 +01:00
Released 9.2.7
This commit is contained in:
@@ -133,9 +133,9 @@ Future<void> _downloadArchive(FortniteBuildDownloadOptions options, Completer st
|
|||||||
throw _genericError;
|
throw _genericError;
|
||||||
},
|
},
|
||||||
headers: byteStart == null || byteStart <= 0 ? {
|
headers: byteStart == null || byteStart <= 0 ? {
|
||||||
"Cookie": "_c_t_c=1"
|
|
||||||
} : {
|
} : {
|
||||||
"Cookie": "_c_t_c=1",
|
|
||||||
"Range": "bytes=${byteStart}-"
|
"Range": "bytes=${byteStart}-"
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ environment:
|
|||||||
sdk: ">=3.0.0 <=4.0.0"
|
sdk: ">=3.0.0 <=4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
dio: ^5.3.2
|
dio: ^5.7.0
|
||||||
win32: 3.0.0
|
win32: 3.0.0
|
||||||
ffi: ^2.1.0
|
ffi: ^2.1.0
|
||||||
path: ^1.8.3
|
path: ^1.8.3
|
||||||
|
|||||||
@@ -368,5 +368,7 @@
|
|||||||
"automaticGameServerDialogStart": "Start server",
|
"automaticGameServerDialogStart": "Start server",
|
||||||
"gameResetDefaultsName": "Reset",
|
"gameResetDefaultsName": "Reset",
|
||||||
"gameResetDefaultsDescription": "Resets the game's settings to their default values",
|
"gameResetDefaultsDescription": "Resets the game's settings to their default values",
|
||||||
"gameResetDefaultsContent": "Reset"
|
"gameResetDefaultsContent": "Reset",
|
||||||
|
"selectFile": "Select a file",
|
||||||
|
"reset": "Reset"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,9 @@ class DllController extends GetxController {
|
|||||||
duration: null
|
duration: null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
timestamp.value = await downloadRebootDll(url.text);
|
final result = downloadRebootDll(url.text);
|
||||||
|
timestamp.value = await Future.wait([result, Future.delayed(const Duration(seconds: 1))], eagerError: false)
|
||||||
|
.then((_) => result);
|
||||||
status.value = UpdateStatus.success;
|
status.value = UpdateStatus.success;
|
||||||
infoBarEntry?.close();
|
infoBarEntry?.close();
|
||||||
if(!silent) {
|
if(!silent) {
|
||||||
@@ -126,15 +128,18 @@ class DllController extends GetxController {
|
|||||||
error = error.contains(": ") ? error.substring(error.indexOf(": ") + 2) : error;
|
error = error.contains(": ") ? error.substring(error.indexOf(": ") + 2) : error;
|
||||||
error = error.toLowerCase();
|
error = error.toLowerCase();
|
||||||
status.value = UpdateStatus.error;
|
status.value = UpdateStatus.error;
|
||||||
showRebootInfoBar(
|
infoBarEntry = showRebootInfoBar(
|
||||||
translations.downloadDllError("reboot.dll", error.toString()),
|
translations.downloadDllError(error.toString(), "reboot.dll"),
|
||||||
duration: infoBarLongDuration,
|
duration: infoBarLongDuration,
|
||||||
severity: InfoBarSeverity.error,
|
severity: InfoBarSeverity.error,
|
||||||
action: Button(
|
action: Button(
|
||||||
onPressed: () => updateGameServerDll(
|
onPressed: () async {
|
||||||
force: true,
|
infoBarEntry?.close();
|
||||||
silent: silent
|
updateGameServerDll(
|
||||||
),
|
force: true,
|
||||||
|
silent: silent
|
||||||
|
);
|
||||||
|
},
|
||||||
child: Text(translations.downloadDllRetry),
|
child: Text(translations.downloadDllRetry),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -215,7 +220,7 @@ class DllController extends GetxController {
|
|||||||
error = error.toLowerCase();
|
error = error.toLowerCase();
|
||||||
final completer = Completer();
|
final completer = Completer();
|
||||||
await showRebootInfoBar(
|
await showRebootInfoBar(
|
||||||
translations.downloadDllError(fileName, error.toString()),
|
translations.downloadDllError(error.toString(), fileName),
|
||||||
duration: infoBarLongDuration,
|
duration: infoBarLongDuration,
|
||||||
severity: InfoBarSeverity.error,
|
severity: InfoBarSeverity.error,
|
||||||
onDismissed: () => completer.complete(null),
|
onDismissed: () => completer.complete(null),
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ void onError(Object exception, StackTrace? stackTrace, bool framework) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastError = exception.toString();
|
lastError = exception.toString();
|
||||||
final route = ModalRoute.of(pageKey.currentContext!);
|
if(inDialog){
|
||||||
if(route != null && !route.isCurrent){
|
final context = pageKey.currentContext;
|
||||||
Navigator.of(pageKey.currentContext!).pop(false);
|
if(context != null) {
|
||||||
|
Navigator.of(context).pop(false);
|
||||||
|
inDialog = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) => showRebootDialog(
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) => showRebootDialog(
|
||||||
|
|||||||
@@ -5,10 +5,13 @@ import 'dart:isolate';
|
|||||||
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:get_storage/get_storage.dart';
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
import 'package:reboot_launcher/src/util/translations.dart';
|
import 'package:reboot_launcher/src/util/translations.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/types.dart';
|
||||||
import 'package:reboot_launcher/src/widget/file_selector.dart';
|
import 'package:reboot_launcher/src/widget/file_selector.dart';
|
||||||
import 'package:universal_disk_space/universal_disk_space.dart';
|
import 'package:universal_disk_space/universal_disk_space.dart';
|
||||||
import 'package:windows_taskbar/windows_taskbar.dart';
|
import 'package:windows_taskbar/windows_taskbar.dart';
|
||||||
@@ -41,6 +44,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
SendPort? _downloadPort;
|
SendPort? _downloadPort;
|
||||||
Object? _error;
|
Object? _error;
|
||||||
StackTrace? _stackTrace;
|
StackTrace? _stackTrace;
|
||||||
|
bool _selecting = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -102,7 +106,12 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
return ErrorDialog(
|
return ErrorDialog(
|
||||||
exception: _error ?? Exception(translations.unknownError),
|
exception: _error ?? Exception(translations.unknownError),
|
||||||
stackTrace: _stackTrace,
|
stackTrace: _stackTrace,
|
||||||
errorMessageBuilder: (exception) => translations.downloadVersionError(exception.toString())
|
errorMessageBuilder: (exception) {
|
||||||
|
var error = exception.toString();
|
||||||
|
error = error.after("Error: ")?.replaceAll(":", ",") ?? error.after(": ") ?? error;
|
||||||
|
error = error.toLowerCase();
|
||||||
|
return translations.downloadVersionError(error);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
case _DownloadStatus.done:
|
case _DownloadStatus.done:
|
||||||
return InfoDialog(
|
return InfoDialog(
|
||||||
@@ -274,7 +283,8 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFormBody(List<FortniteBuild> builds) => Column(
|
Widget _buildFormBody(List<FortniteBuild> builds) {
|
||||||
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -292,7 +302,8 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
windowTitle: _source.value == _BuildSource.local ? translations.gameFolderPlaceWindowTitle : translations.buildInstallationDirectoryWindowTitle,
|
windowTitle: _source.value == _BuildSource.local ? translations.gameFolderPlaceWindowTitle : translations.buildInstallationDirectoryWindowTitle,
|
||||||
controller: _pathController,
|
controller: _pathController,
|
||||||
validator: _source.value == _BuildSource.local ? _checkGameFolder : _checkDownloadDestination,
|
validator: _source.value == _BuildSource.local ? _checkGameFolder : _checkDownloadDestination,
|
||||||
folder: true
|
folder: true,
|
||||||
|
allowNavigator: true
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@@ -300,6 +311,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
String? _checkGameFolder(text) {
|
String? _checkGameFolder(text) {
|
||||||
if (text == null || text.isEmpty) {
|
if (text == null || text.isEmpty) {
|
||||||
|
|||||||
@@ -153,9 +153,9 @@ class _BackendPageState extends RebootPageState<BackendPage> {
|
|||||||
contentWidth: null,
|
contentWidth: null,
|
||||||
content: Row(
|
content: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Obx(() => Text(
|
||||||
_backendController.detached.value ? translations.on : translations.off
|
_backendController.detached.value ? translations.on : translations.off
|
||||||
),
|
)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16.0
|
width: 16.0
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -298,48 +298,46 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody() {
|
Widget _buildBody() => Expanded(
|
||||||
return Expanded(
|
child: Padding(
|
||||||
child: Padding(
|
padding: EdgeInsets.only(
|
||||||
padding: EdgeInsets.only(
|
left: HomePage.kDefaultPadding,
|
||||||
left: HomePage.kDefaultPadding,
|
right: HomePage.kDefaultPadding * 2,
|
||||||
right: HomePage.kDefaultPadding * 2,
|
top: HomePage.kDefaultPadding,
|
||||||
top: HomePage.kDefaultPadding,
|
bottom: HomePage.kDefaultPadding * 2
|
||||||
bottom: HomePage.kDefaultPadding * 2
|
),
|
||||||
),
|
child: Column(
|
||||||
child: Column(
|
children: [
|
||||||
children: [
|
Expanded(
|
||||||
Expanded(
|
child: ConstrainedBox(
|
||||||
child: ConstrainedBox(
|
constraints: BoxConstraints(
|
||||||
constraints: BoxConstraints(
|
maxWidth: 1000
|
||||||
maxWidth: 1000
|
),
|
||||||
),
|
child: Center(
|
||||||
child: Center(
|
child: Column(
|
||||||
child: Column(
|
children: [
|
||||||
children: [
|
_buildBodyHeader(),
|
||||||
_buildBodyHeader(),
|
const SizedBox(height: 24.0),
|
||||||
const SizedBox(height: 24.0),
|
Expanded(
|
||||||
Expanded(
|
child: Stack(
|
||||||
child: Stack(
|
fit: StackFit.loose,
|
||||||
fit: StackFit.loose,
|
children: [
|
||||||
children: [
|
_buildBodyContent(),
|
||||||
_buildBodyContent(),
|
InfoBarArea(
|
||||||
InfoBarArea(
|
key: infoBarAreaKey
|
||||||
key: infoBarAreaKey
|
)
|
||||||
)
|
],
|
||||||
],
|
)
|
||||||
)
|
),
|
||||||
),
|
],
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
)
|
||||||
)
|
],
|
||||||
),
|
)
|
||||||
);
|
),
|
||||||
}
|
);
|
||||||
|
|
||||||
Widget _buildBodyContent() => PageView.builder(
|
Widget _buildBodyContent() => PageView.builder(
|
||||||
controller: _pageController,
|
controller: _pageController,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
|||||||
List<Widget> get settings => [
|
List<Widget> get settings => [
|
||||||
_information,
|
_information,
|
||||||
buildVersionSelector(
|
buildVersionSelector(
|
||||||
key: hostVersionOverlayTargetKey
|
key: hostVersionOverlayTargetKey
|
||||||
),
|
),
|
||||||
_options,
|
_options,
|
||||||
_internalFiles,
|
_internalFiles,
|
||||||
@@ -175,9 +175,9 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
|||||||
contentWidth: null,
|
contentWidth: null,
|
||||||
content: Obx(() => Row(
|
content: Obx(() => Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Obx(() => Text(
|
||||||
_hostingController.discoverable.value ? translations.on : translations.off
|
_hostingController.discoverable.value ? translations.on : translations.off
|
||||||
),
|
)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16.0
|
width: 16.0
|
||||||
),
|
),
|
||||||
@@ -226,7 +226,7 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
|||||||
text: Text(entry.translatedName),
|
text: Text(entry.translatedName),
|
||||||
onPressed: () => _hostingController.type.value = entry
|
onPressed: () => _hostingController.type.value = entry
|
||||||
)).toList(),
|
)).toList(),
|
||||||
disabled: _settingsController.debug.value
|
disabled: _settingsController.debug.value
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
SettingTile(
|
SettingTile(
|
||||||
@@ -238,9 +238,9 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
|||||||
contentWidth: null,
|
contentWidth: null,
|
||||||
content: Row(
|
content: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Obx(() => Text(
|
||||||
_hostingController.autoRestart.value ? translations.on : translations.off
|
_hostingController.autoRestart.value ? translations.on : translations.off
|
||||||
),
|
)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16.0
|
width: 16.0
|
||||||
),
|
),
|
||||||
@@ -278,151 +278,143 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
|||||||
title: Text(translations.settingsServerName),
|
title: Text(translations.settingsServerName),
|
||||||
subtitle: Text(translations.settingsServerSubtitle),
|
subtitle: Text(translations.settingsServerSubtitle),
|
||||||
children: [
|
children: [
|
||||||
SettingTile(
|
_internalFilesServerType,
|
||||||
icon: Icon(
|
_internalFilesUpdateTimer,
|
||||||
FluentIcons.timer_24_regular
|
_internalFilesServerSource
|
||||||
),
|
],
|
||||||
title: Text(translations.settingsServerTypeName),
|
);
|
||||||
subtitle: Text(translations.settingsServerTypeDescription),
|
|
||||||
content: Obx(() => DropDownButton(
|
|
||||||
onOpen: () => inDialog = true,
|
|
||||||
onClose: () => inDialog = false,
|
|
||||||
leading: Text(_dllController.customGameServer.value ? translations.settingsServerTypeCustomName : translations.settingsServerTypeEmbeddedName),
|
|
||||||
items: {
|
|
||||||
false: translations.settingsServerTypeEmbeddedName,
|
|
||||||
true: translations.settingsServerTypeCustomName
|
|
||||||
}.entries.map((entry) => MenuFlyoutItem(
|
|
||||||
text: Text(entry.value),
|
|
||||||
onPressed: () {
|
|
||||||
final oldValue = _dllController.customGameServer.value;
|
|
||||||
if(oldValue == entry.key) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dllController.customGameServer.value = entry.key;
|
Widget get _internalFilesServerType => SettingTile(
|
||||||
_dllController.infoBarEntry?.close();
|
icon: Icon(
|
||||||
if(!entry.key) {
|
FluentIcons.games_24_regular
|
||||||
_dllController.updateGameServerDll(
|
|
||||||
force: true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)).toList()
|
|
||||||
))
|
|
||||||
),
|
),
|
||||||
Obx(() {
|
title: Text(translations.settingsServerTypeName),
|
||||||
if(!_dllController.customGameServer.value) {
|
subtitle: Text(translations.settingsServerTypeDescription),
|
||||||
return const SizedBox.shrink();
|
contentWidth: SettingTile.kDefaultContentWidth + 30,
|
||||||
}
|
content: Obx(() => DropDownButton(
|
||||||
|
onOpen: () => inDialog = true,
|
||||||
|
onClose: () => inDialog = false,
|
||||||
|
leading: Text(_dllController.customGameServer.value ? translations.settingsServerTypeCustomName : translations.settingsServerTypeEmbeddedName),
|
||||||
|
items: {
|
||||||
|
false: translations.settingsServerTypeEmbeddedName,
|
||||||
|
true: translations.settingsServerTypeCustomName
|
||||||
|
}.entries.map((entry) => MenuFlyoutItem(
|
||||||
|
text: Text(entry.value),
|
||||||
|
onPressed: () {
|
||||||
|
final oldValue = _dllController.customGameServer.value;
|
||||||
|
if(oldValue == entry.key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return createFileSetting(
|
_dllController.customGameServer.value = entry.key;
|
||||||
title: translations.settingsServerFileName,
|
_dllController.infoBarEntry?.close();
|
||||||
description: translations.settingsServerFileDescription,
|
if(!entry.key) {
|
||||||
controller: _dllController.gameServerDll,
|
_dllController.updateGameServerDll(
|
||||||
onReset: () {
|
force: true
|
||||||
final path = _dllController.getDefaultDllPath(InjectableDll.reboot);
|
);
|
||||||
_dllController.gameServerDll.text = path;
|
}
|
||||||
_dllController.downloadCriticalDllInteractive(path);
|
}
|
||||||
}
|
)).toList()
|
||||||
);
|
))
|
||||||
}),
|
);
|
||||||
Obx(() {
|
|
||||||
if(_dllController.customGameServer.value) {
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
|
|
||||||
return SettingTile(
|
Widget get _internalFilesServerSource => Obx(() {
|
||||||
icon: Icon(
|
if(!_dllController.customGameServer.value) {
|
||||||
FluentIcons.globe_24_regular
|
return SettingTile(
|
||||||
),
|
icon: Icon(
|
||||||
title: Text(translations.settingsServerMirrorName),
|
FluentIcons.globe_24_regular
|
||||||
subtitle: Text(translations.settingsServerMirrorDescription),
|
),
|
||||||
content: Row(
|
title: Text(translations.settingsServerMirrorName),
|
||||||
children: [
|
subtitle: Text(translations.settingsServerMirrorDescription),
|
||||||
Expanded(
|
contentWidth: SettingTile.kDefaultContentWidth + 30,
|
||||||
child: TextFormBox(
|
content: Row(
|
||||||
placeholder: translations.settingsServerMirrorPlaceholder,
|
children: [
|
||||||
controller: _dllController.url,
|
Expanded(
|
||||||
validator: _checkUpdateUrl
|
child: TextFormBox(
|
||||||
),
|
placeholder: translations.settingsServerMirrorPlaceholder,
|
||||||
),
|
controller: _dllController.url,
|
||||||
const SizedBox(width: 8.0),
|
onChanged: (value) {
|
||||||
Button(
|
if(Uri.tryParse(value) != null) {
|
||||||
style: ButtonStyle(
|
_dllController.updateGameServerDll(force: true);
|
||||||
padding: ButtonState.all(EdgeInsets.zero)
|
}
|
||||||
),
|
|
||||||
onPressed: () => _dllController.url.text = kRebootDownloadUrl,
|
|
||||||
child: SizedBox.square(
|
|
||||||
dimension: 30,
|
|
||||||
child: Icon(
|
|
||||||
FluentIcons.arrow_reset_24_regular
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
Obx(() {
|
|
||||||
if(_dllController.customGameServer.value) {
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
|
|
||||||
return SettingTile(
|
|
||||||
icon: Icon(
|
|
||||||
FluentIcons.timer_24_regular
|
|
||||||
),
|
|
||||||
title: Text(translations.settingsServerTimerName),
|
|
||||||
subtitle: Text(translations.settingsServerTimerSubtitle),
|
|
||||||
content: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Obx(() => DropDownButton(
|
|
||||||
onOpen: () => inDialog = true,
|
|
||||||
onClose: () => inDialog = false,
|
|
||||||
leading: Text(_dllController.timer.value.text),
|
|
||||||
items: UpdateTimer.values.map((entry) => MenuFlyoutItem(
|
|
||||||
text: Text(entry.text),
|
|
||||||
onPressed: () {
|
|
||||||
_dllController.timer.value = entry;
|
|
||||||
_dllController.infoBarEntry?.close();
|
|
||||||
_dllController.updateGameServerDll(
|
|
||||||
force: true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)).toList()
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8.0),
|
|
||||||
Button(
|
|
||||||
style: ButtonStyle(
|
|
||||||
padding: ButtonState.all(EdgeInsets.zero)
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
_dllController.updateGameServerDll(force: true);
|
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8.0),
|
||||||
|
Button(
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: ButtonState.all(EdgeInsets.zero)
|
||||||
|
),
|
||||||
|
onPressed: () => _dllController.updateGameServerDll(force: true),
|
||||||
child: SizedBox.square(
|
child: SizedBox.square(
|
||||||
dimension: 30,
|
dimension: 30,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
FluentIcons.arrow_download_24_regular
|
FluentIcons.arrow_download_24_regular
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
],
|
const SizedBox(width: 8.0),
|
||||||
)
|
Button(
|
||||||
);
|
style: ButtonStyle(
|
||||||
})
|
padding: ButtonState.all(EdgeInsets.zero)
|
||||||
],
|
),
|
||||||
);
|
onPressed: () {
|
||||||
|
_dllController.url.text = kRebootDownloadUrl;
|
||||||
|
_dllController.updateGameServerDll(force: true);
|
||||||
|
},
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: 30,
|
||||||
|
child: Icon(
|
||||||
|
FluentIcons.arrow_reset_24_regular
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}else {
|
||||||
|
return createFileSetting(
|
||||||
|
title: translations.settingsServerFileName,
|
||||||
|
description: translations.settingsServerFileDescription,
|
||||||
|
controller: _dllController.gameServerDll,
|
||||||
|
onReset: () {
|
||||||
|
final path = _dllController.getDefaultDllPath(InjectableDll.reboot);
|
||||||
|
_dllController.gameServerDll.text = path;
|
||||||
|
_dllController.downloadCriticalDllInteractive(path);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Widget get _internalFilesUpdateTimer => Obx(() {
|
||||||
String? _checkUpdateUrl(String? text) {
|
if(_dllController.customGameServer.value) {
|
||||||
if (text == null || text.isEmpty) {
|
return const SizedBox.shrink();
|
||||||
return translations.emptyURL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return SettingTile(
|
||||||
}
|
icon: Icon(
|
||||||
|
FluentIcons.timer_24_regular
|
||||||
|
),
|
||||||
|
title: Text(translations.settingsServerTimerName),
|
||||||
|
subtitle: Text(translations.settingsServerTimerSubtitle),
|
||||||
|
contentWidth: SettingTile.kDefaultContentWidth + 30,
|
||||||
|
content: Obx(() => DropDownButton(
|
||||||
|
onOpen: () => inDialog = true,
|
||||||
|
onClose: () => inDialog = false,
|
||||||
|
leading: Text(_dllController.timer.value.text),
|
||||||
|
items: UpdateTimer.values.map((entry) => MenuFlyoutItem(
|
||||||
|
text: Text(entry.text),
|
||||||
|
onPressed: () {
|
||||||
|
_dllController.timer.value = entry;
|
||||||
|
_dllController.infoBarEntry?.close();
|
||||||
|
_dllController.updateGameServerDll(
|
||||||
|
force: true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)).toList()
|
||||||
|
))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
SettingTile get _share => SettingTile(
|
SettingTile get _share => SettingTile(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ class _SettingsPageState extends RebootPageState<SettingsPage> {
|
|||||||
contentWidth: null,
|
contentWidth: null,
|
||||||
content: Row(
|
content: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Obx(() => Text(
|
||||||
_settingsController.debug.value ? translations.on : translations.off
|
_settingsController.debug.value ? translations.on : translations.off
|
||||||
),
|
)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16.0
|
width: 16.0
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,4 +5,15 @@ extension IterableExtension<E> on Iterable<E> {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StringExtension on String {
|
||||||
|
String? after(String leading) {
|
||||||
|
final index = indexOf(leading);
|
||||||
|
if(index == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return substring(index + leading.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,10 +19,10 @@ class FileSelector extends StatefulWidget {
|
|||||||
required this.controller,
|
required this.controller,
|
||||||
required this.validator,
|
required this.validator,
|
||||||
required this.folder,
|
required this.folder,
|
||||||
|
required this.allowNavigator,
|
||||||
this.label,
|
this.label,
|
||||||
this.extension,
|
this.extension,
|
||||||
this.validatorMode,
|
this.validatorMode,
|
||||||
this.allowNavigator = true,
|
|
||||||
Key? key})
|
Key? key})
|
||||||
: assert(folder || extension != null, "Missing extension for file selector"),
|
: assert(folder || extension != null, "Missing extension for file selector"),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|||||||
@@ -1,70 +1,120 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons;
|
import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons;
|
||||||
|
import 'package:fluent_ui/fluent_ui.dart' as fluentIcons show FluentIcons;
|
||||||
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:reboot_launcher/src/util/os.dart';
|
||||||
import 'package:reboot_launcher/src/util/translations.dart';
|
import 'package:reboot_launcher/src/util/translations.dart';
|
||||||
import 'package:reboot_launcher/src/widget/file_selector.dart';
|
import 'package:reboot_launcher/src/widget/file_selector.dart';
|
||||||
import 'package:reboot_launcher/src/widget/setting_tile.dart';
|
import 'package:reboot_launcher/src/widget/setting_tile.dart';
|
||||||
|
|
||||||
|
const double _kButtonDimensions = 30;
|
||||||
|
const double _kButtonSpacing = 8;
|
||||||
|
|
||||||
SettingTile createFileSetting({required String title, required String description, required TextEditingController controller, required void Function() onReset}) {
|
SettingTile createFileSetting({required String title, required String description, required TextEditingController controller, required void Function() onReset}) {
|
||||||
final obx = RxString(controller.text);
|
final obx = RxString(controller.text);
|
||||||
controller.addListener(() => obx.value = controller.text);
|
controller.addListener(() => obx.value = controller.text);
|
||||||
return SettingTile(
|
final selecting = RxBool(false);
|
||||||
icon: Icon(
|
return SettingTile(
|
||||||
FluentIcons.document_24_regular
|
icon: Icon(
|
||||||
),
|
FluentIcons.document_24_regular
|
||||||
title: Text(title),
|
),
|
||||||
subtitle: Text(description),
|
title: Text(title),
|
||||||
content: Row(
|
subtitle: Text(description),
|
||||||
|
contentWidth: SettingTile.kDefaultContentWidth + _kButtonDimensions * 2 + _kButtonSpacing * 2,
|
||||||
|
content: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FileSelector(
|
child: FileSelector(
|
||||||
placeholder: translations.selectPathPlaceholder,
|
placeholder: translations.selectPathPlaceholder,
|
||||||
windowTitle: translations.selectPathWindowTitle,
|
windowTitle: translations.selectPathWindowTitle,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
validator: _checkDll,
|
validator: _checkDll,
|
||||||
extension: "dll",
|
extension: "dll",
|
||||||
folder: false,
|
folder: false,
|
||||||
validatorMode: AutovalidateMode.always
|
validatorMode: AutovalidateMode.always,
|
||||||
),
|
allowNavigator: false,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8.0),
|
),
|
||||||
Obx(() => Padding(
|
const SizedBox(width: _kButtonSpacing),
|
||||||
padding: EdgeInsets.only(
|
Obx(() => Padding(
|
||||||
bottom: _checkDll(obx.value) == null ? 0.0 : 20.0
|
padding: EdgeInsets.only(
|
||||||
|
bottom: _checkDll(obx.value) == null ? 0.0 : 20.0
|
||||||
|
),
|
||||||
|
child: Tooltip(
|
||||||
|
message: translations.selectFile,
|
||||||
|
child: Button(
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: ButtonState.all(EdgeInsets.zero)
|
||||||
|
),
|
||||||
|
onPressed: () => _onPressed(selecting, controller),
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: _kButtonDimensions,
|
||||||
|
child: Icon(
|
||||||
|
fluentIcons.FluentIcons.open_folder_horizontal
|
||||||
|
),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
const SizedBox(width: _kButtonSpacing),
|
||||||
|
Obx(() => Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: _checkDll(obx.value) == null ? 0.0 : 20.0
|
||||||
|
),
|
||||||
|
child: Tooltip(
|
||||||
|
message: translations.reset,
|
||||||
child: Button(
|
child: Button(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: ButtonState.all(EdgeInsets.zero)
|
padding: ButtonState.all(EdgeInsets.zero)
|
||||||
),
|
),
|
||||||
onPressed: onReset,
|
onPressed: onReset,
|
||||||
child: SizedBox.square(
|
child: SizedBox.square(
|
||||||
dimension: 30,
|
dimension: _kButtonDimensions,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
FluentIcons.arrow_reset_24_regular
|
FluentIcons.arrow_reset_24_regular
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
))
|
),
|
||||||
|
))
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onPressed(RxBool selecting, TextEditingController controller) {
|
||||||
|
if(selecting.value){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selecting.value = true;
|
||||||
|
compute(openFilePicker, "dll")
|
||||||
|
.then((value) => _updateText(controller, value))
|
||||||
|
.then((_) => selecting.value = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateText(TextEditingController controller, String? value) {
|
||||||
|
final text = value ?? controller.text;
|
||||||
|
controller.text = text;
|
||||||
|
controller.selection = TextSelection.collapsed(offset: text.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _checkDll(String? text) {
|
String? _checkDll(String? text) {
|
||||||
if (text == null || text.isEmpty) {
|
if (text == null || text.isEmpty) {
|
||||||
return translations.invalidDllPath;
|
return translations.invalidDllPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
final file = File(text);
|
final file = File(text);
|
||||||
if (!file.existsSync()) {
|
if (!file.existsSync()) {
|
||||||
return translations.dllDoesNotExist;
|
return translations.dllDoesNotExist;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!text.endsWith(".dll")) {
|
if (!text.endsWith(".dll")) {
|
||||||
return translations.invalidDllExtension;
|
return translations.invalidDllExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -24,19 +24,22 @@ class InfoBarAreaState extends State<InfoBarArea> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Obx(() => Padding(
|
Widget build(BuildContext context) => StreamBuilder(
|
||||||
padding: EdgeInsets.only(
|
stream: pagesController.stream,
|
||||||
bottom: hasPageButton ? 72.0 : 16.0
|
builder: (context, _) => Obx(() => Padding(
|
||||||
),
|
padding: EdgeInsets.only(
|
||||||
child: Column(
|
bottom: hasPageButton ? 72.0 : 16.0
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: _children.value.map((child) => Padding(
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
padding: EdgeInsets.only(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
top: 12.0
|
children: _children.value.map((child) => Padding(
|
||||||
),
|
padding: EdgeInsets.only(
|
||||||
child: child
|
top: 12.0
|
||||||
)).toList(growable: false)
|
),
|
||||||
),
|
child: child
|
||||||
));
|
)).toList(growable: false)
|
||||||
|
),
|
||||||
|
))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: reboot_launcher
|
name: reboot_launcher
|
||||||
description: Graphical User Interface for Project Reboot
|
description: Graphical User Interface for Project Reboot
|
||||||
version: "9.2.6"
|
version: "9.2.7"
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user