mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 11:12:23 +01:00
9.0.8
This commit is contained in:
@@ -1,43 +1,235 @@
|
||||
import 'dart:async';
|
||||
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_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page_type.dart';
|
||||
import 'package:reboot_launcher/src/util/translations.dart';
|
||||
|
||||
class BackendController extends ServerController {
|
||||
late RxBool detached;
|
||||
class BackendController extends GetxController {
|
||||
late final GetStorage storage;
|
||||
late final TextEditingController host;
|
||||
late final TextEditingController port;
|
||||
late final Rx<ServerType> type;
|
||||
late final TextEditingController gameServerAddress;
|
||||
late final FocusNode gameServerAddressFocusNode;
|
||||
late final RxnString gameServerOwner;
|
||||
late final RxBool started;
|
||||
late final RxBool detached;
|
||||
StreamSubscription? worker;
|
||||
HttpServer? localServer;
|
||||
HttpServer? remoteServer;
|
||||
|
||||
BackendController() : super() {
|
||||
BackendController() {
|
||||
storage = GetStorage("backend");
|
||||
started = RxBool(false);
|
||||
type = Rx(ServerType.values.elementAt(storage.read("type") ?? 0));
|
||||
type.listen((value) {
|
||||
host.text = _readHost();
|
||||
port.text = _readPort();
|
||||
storage.write("type", value.index);
|
||||
if (!started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
stop();
|
||||
});
|
||||
host = TextEditingController(text: _readHost());
|
||||
host.addListener(() =>
|
||||
storage.write("${type.value.name}_host", host.text));
|
||||
port = TextEditingController(text: _readPort());
|
||||
port.addListener(() =>
|
||||
storage.write("${type.value.name}_port", port.text));
|
||||
detached = RxBool(storage.read("detached") ?? false);
|
||||
detached.listen((value) => storage.write("detached", value));
|
||||
gameServerAddress = TextEditingController(text: storage.read("game_server_address") ?? "127.0.0.1");
|
||||
var lastValue = gameServerAddress.text;
|
||||
writeMatchmakingIp(lastValue);
|
||||
gameServerAddress.addListener(() {
|
||||
var newValue = gameServerAddress.text;
|
||||
if(newValue.trim().toLowerCase() == lastValue.trim().toLowerCase()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastValue = newValue;
|
||||
gameServerAddress.selection = TextSelection.collapsed(offset: newValue.length);
|
||||
storage.write("game_server_address", newValue);
|
||||
writeMatchmakingIp(newValue);
|
||||
});
|
||||
watchMatchmakingIp().listen((event) {
|
||||
if(event != null && gameServerAddress.text != event) {
|
||||
gameServerAddress.text = event;
|
||||
}
|
||||
});
|
||||
gameServerAddressFocusNode = FocusNode();
|
||||
gameServerOwner = RxnString(storage.read("game_server_owner"));
|
||||
gameServerOwner.listen((value) => storage.write("game_server_owner", value));
|
||||
}
|
||||
|
||||
@override
|
||||
String get controllerName => translations.backendName.toLowerCase();
|
||||
void reset() async {
|
||||
type.value = ServerType.values.elementAt(0);
|
||||
for (final type in ServerType.values) {
|
||||
storage.write("${type.name}_host", null);
|
||||
storage.write("${type.name}_port", null);
|
||||
}
|
||||
|
||||
@override
|
||||
String get storageName => "backend";
|
||||
host.text = type.value != ServerType.remote ? kDefaultBackendHost : "";
|
||||
port.text = kDefaultBackendPort.toString();
|
||||
detached.value = false;
|
||||
}
|
||||
|
||||
@override
|
||||
String get defaultHost => kDefaultBackendHost;
|
||||
String _readHost() {
|
||||
String? value = storage.read("${type.value.name}_host");
|
||||
if (value != null && value.isNotEmpty) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@override
|
||||
int get defaultPort => kDefaultBackendPort;
|
||||
if (type.value != ServerType.remote) {
|
||||
return kDefaultBackendHost;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get isPortFree => isBackendPortFree();
|
||||
return "";
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> freePort() => freeBackendPort();
|
||||
String _readPort() =>
|
||||
storage.read("${type.value.name}_port") ?? kDefaultBackendPort.toString();
|
||||
|
||||
@override
|
||||
RebootPageType get pageType => RebootPageType.backend;
|
||||
Stream<ServerResult> start() async* {
|
||||
try {
|
||||
if(started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Process> startEmbeddedInternal() => startEmbeddedBackend(detached.value);
|
||||
final hostData = this.host.text.trim();
|
||||
final portData = this.port.text.trim();
|
||||
if(type() != ServerType.local) {
|
||||
started.value = true;
|
||||
yield ServerResult(ServerResultType.starting);
|
||||
}else {
|
||||
started.value = false;
|
||||
if(portData != kDefaultBackendPort.toString()) {
|
||||
yield ServerResult(ServerResultType.starting);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uri?> pingServer(String host, int port) => pingBackend(host, port);
|
||||
if (hostData.isEmpty) {
|
||||
yield ServerResult(ServerResultType.missingHostError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (portData.isEmpty) {
|
||||
yield ServerResult(ServerResultType.missingPortError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
final portNumber = int.tryParse(portData);
|
||||
if (portNumber == null) {
|
||||
yield ServerResult(ServerResultType.illegalPortError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((type() != ServerType.local || portData != kDefaultBackendPort.toString()) && !(await isBackendPortFree())) {
|
||||
yield ServerResult(ServerResultType.freeingPort);
|
||||
final result = await freeBackendPort();
|
||||
yield ServerResult(result ? ServerResultType.freePortSuccess : ServerResultType.freePortError);
|
||||
if(!result) {
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(type()){
|
||||
case ServerType.embedded:
|
||||
final process = await startEmbeddedBackend(detached.value);
|
||||
final processPid = process.pid;
|
||||
watchProcess(processPid).then((value) {
|
||||
if(started()) {
|
||||
started.value = false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ServerType.remote:
|
||||
yield ServerResult(ServerResultType.pingingRemote);
|
||||
final uriResult = await pingBackend(hostData, portNumber);
|
||||
if(uriResult == null) {
|
||||
yield ServerResult(ServerResultType.pingError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
remoteServer = await startRemoteBackendProxy(uriResult);
|
||||
break;
|
||||
case ServerType.local:
|
||||
if(portData != kDefaultBackendPort.toString()) {
|
||||
localServer = await startRemoteBackendProxy(Uri.parse("http://$kDefaultBackendHost:$portData"));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.pingingLocal);
|
||||
final uriResult = await pingBackend(kDefaultBackendHost, kDefaultBackendPort);
|
||||
if(uriResult == null) {
|
||||
yield ServerResult(ServerResultType.pingError);
|
||||
remoteServer?.close(force: true);
|
||||
localServer?.close(force: true);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.startSuccess);
|
||||
}catch(error, stackTrace) {
|
||||
yield ServerResult(
|
||||
ServerResultType.startError,
|
||||
error: error,
|
||||
stackTrace: stackTrace
|
||||
);
|
||||
remoteServer?.close(force: true);
|
||||
localServer?.close(force: true);
|
||||
started.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<ServerResult> stop() async* {
|
||||
if(!started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.stopping);
|
||||
started.value = false;
|
||||
try{
|
||||
switch(type()){
|
||||
case ServerType.embedded:
|
||||
killProcessByPort(kDefaultBackendPort);
|
||||
break;
|
||||
case ServerType.remote:
|
||||
await remoteServer?.close(force: true);
|
||||
remoteServer = null;
|
||||
break;
|
||||
case ServerType.local:
|
||||
await localServer?.close(force: true);
|
||||
localServer = null;
|
||||
break;
|
||||
}
|
||||
yield ServerResult(ServerResultType.stopSuccess);
|
||||
}catch(error, stackTrace){
|
||||
yield ServerResult(
|
||||
ServerResultType.stopError,
|
||||
error: error,
|
||||
stackTrace: stackTrace
|
||||
);
|
||||
started.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<ServerResult> toggle() async* {
|
||||
if(started()) {
|
||||
yield* stop();
|
||||
}else {
|
||||
yield* start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,8 @@ import 'package:reboot_common/common.dart';
|
||||
class BuildController extends GetxController {
|
||||
List<FortniteBuild>? _builds;
|
||||
Rxn<FortniteBuild> _selectedBuild;
|
||||
Rx<FortniteBuildSource> _selectedBuildSource;
|
||||
|
||||
BuildController() : _selectedBuild = Rxn(),
|
||||
_selectedBuildSource = Rx(FortniteBuildSource.manifest);
|
||||
BuildController() : _selectedBuild = Rxn();
|
||||
|
||||
List<FortniteBuild>? get builds => _builds;
|
||||
|
||||
@@ -15,26 +13,10 @@ class BuildController extends GetxController {
|
||||
|
||||
set selectedBuild(FortniteBuild? value) {
|
||||
_selectedBuild.value = value;
|
||||
if(value != null && value.source != value.source) {
|
||||
_selectedBuildSource.value = value.source;
|
||||
}
|
||||
}
|
||||
|
||||
FortniteBuildSource get selectedBuildSource => _selectedBuildSource.value;
|
||||
|
||||
set selectedBuildSource(FortniteBuildSource value) {
|
||||
_selectedBuildSource.value = value;
|
||||
final selected = selectedBuild;
|
||||
if(selected == null || selected.source != value) {
|
||||
final selectable = builds?.firstWhereOrNull((element) => element.source == value);
|
||||
_selectedBuild.value = selectable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set builds(List<FortniteBuild>? builds) {
|
||||
_builds = builds;
|
||||
final selectable = builds?.firstWhereOrNull((element) => element.source == selectedBuildSource);
|
||||
_selectedBuild.value = selectable;
|
||||
_selectedBuild.value = builds?.firstOrNull;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class HostingController extends GetxController {
|
||||
late final RxBool discoverable;
|
||||
late final RxBool headless;
|
||||
late final RxBool virtualDesktop;
|
||||
late final RxBool autoRestart;
|
||||
late final RxBool started;
|
||||
late final RxBool published;
|
||||
late final Rxn<GameInstance> instance;
|
||||
@@ -36,6 +37,8 @@ class HostingController extends GetxController {
|
||||
headless.listen((value) => _storage.write("headless", value));
|
||||
virtualDesktop = RxBool(_storage.read("virtual_desktop") ?? true);
|
||||
virtualDesktop.listen((value) => _storage.write("virtual_desktop", value));
|
||||
autoRestart = RxBool(_storage.read("auto_restart") ?? true);
|
||||
autoRestart.listen((value) => _storage.write("auto_restart", value));
|
||||
started = RxBool(false);
|
||||
published = RxBool(false);
|
||||
showPassword = RxBool(false);
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:get/get_rx/src/rx_types/rx_types.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page_type.dart';
|
||||
import 'package:reboot_launcher/src/util/translations.dart';
|
||||
|
||||
class MatchmakerController extends ServerController {
|
||||
late final TextEditingController gameServerAddress;
|
||||
late final FocusNode gameServerAddressFocusNode;
|
||||
late final RxnString gameServerOwner;
|
||||
|
||||
MatchmakerController() : super() {
|
||||
gameServerAddress = TextEditingController(text: storage.read("game_server_address") ?? kDefaultMatchmakerHost);
|
||||
var lastValue = gameServerAddress.text;
|
||||
writeMatchmakingIp(lastValue);
|
||||
gameServerAddress.addListener(() {
|
||||
var newValue = gameServerAddress.text;
|
||||
if(newValue.trim().toLowerCase() == lastValue.trim().toLowerCase()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastValue = newValue;
|
||||
gameServerAddress.selection = TextSelection.collapsed(offset: newValue.length);
|
||||
storage.write("game_server_address", newValue);
|
||||
writeMatchmakingIp(newValue);
|
||||
});
|
||||
watchMatchmakingIp().listen((event) {
|
||||
if(event != null && gameServerAddress.text != event) {
|
||||
gameServerAddress.text = event;
|
||||
}
|
||||
});
|
||||
gameServerAddressFocusNode = FocusNode();
|
||||
gameServerOwner = RxnString(storage.read("game_server_owner"));
|
||||
gameServerOwner.listen((value) => storage.write("game_server_owner", value));
|
||||
}
|
||||
|
||||
@override
|
||||
String get controllerName => translations.matchmakerName.toLowerCase();
|
||||
|
||||
@override
|
||||
String get storageName => "matchmaker";
|
||||
|
||||
@override
|
||||
String get defaultHost => kDefaultMatchmakerHost;
|
||||
|
||||
@override
|
||||
int get defaultPort => kDefaultMatchmakerPort;
|
||||
|
||||
@override
|
||||
Future<bool> get isPortFree => isMatchmakerPortFree();
|
||||
|
||||
@override
|
||||
Future<bool> freePort() => freeMatchmakerPort();
|
||||
|
||||
@override
|
||||
RebootPageType get pageType => RebootPageType.matchmaker;
|
||||
|
||||
@override
|
||||
Future<Process> startEmbeddedInternal() => startEmbeddedMatchmaker();
|
||||
|
||||
@override
|
||||
Future<Uri?> pingServer(String host, int port) => pingMatchmaker(host, port);
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
import 'dart:async';
|
||||
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_common/common.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page_type.dart';
|
||||
import 'package:sync/semaphore.dart';
|
||||
|
||||
abstract class ServerController extends GetxController {
|
||||
late final GetStorage storage;
|
||||
late final TextEditingController host;
|
||||
late final TextEditingController port;
|
||||
late final Rx<ServerType> type;
|
||||
late final Semaphore semaphore;
|
||||
late RxBool started;
|
||||
StreamSubscription? worker;
|
||||
HttpServer? localServer;
|
||||
HttpServer? remoteServer;
|
||||
|
||||
ServerController() {
|
||||
storage = GetStorage(storageName);
|
||||
started = RxBool(false);
|
||||
type = Rx(ServerType.values.elementAt(storage.read("type") ?? 0));
|
||||
type.listen((value) {
|
||||
host.text = _readHost();
|
||||
port.text = _readPort();
|
||||
storage.write("type", value.index);
|
||||
if (!started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
stop();
|
||||
});
|
||||
host = TextEditingController(text: _readHost());
|
||||
host.addListener(() =>
|
||||
storage.write("${type.value.name}_host", host.text));
|
||||
port = TextEditingController(text: _readPort());
|
||||
port.addListener(() =>
|
||||
storage.write("${type.value.name}_port", port.text));
|
||||
semaphore = Semaphore();
|
||||
}
|
||||
|
||||
String get controllerName;
|
||||
|
||||
String get storageName;
|
||||
|
||||
String get defaultHost;
|
||||
|
||||
int get defaultPort;
|
||||
|
||||
Future<Uri?> pingServer(String host, int port);
|
||||
|
||||
Future<bool> get isPortFree;
|
||||
|
||||
Future<bool> get isPortTaken async => !(await isPortFree);
|
||||
|
||||
RebootPageType get pageType;
|
||||
|
||||
Future<bool> freePort();
|
||||
|
||||
@protected
|
||||
Future<Process> startEmbeddedInternal();
|
||||
|
||||
void reset() async {
|
||||
type.value = ServerType.values.elementAt(0);
|
||||
for (final type in ServerType.values) {
|
||||
storage.write("${type.name}_host", null);
|
||||
storage.write("${type.name}_port", null);
|
||||
}
|
||||
|
||||
host.text = type.value != ServerType.remote ? defaultHost : "";
|
||||
port.text = defaultPort.toString();
|
||||
detached.value = false;
|
||||
}
|
||||
|
||||
String _readHost() {
|
||||
String? value = storage.read("${type.value.name}_host");
|
||||
return value != null && value.isNotEmpty ? value
|
||||
: type.value != ServerType.remote ? defaultHost : "";
|
||||
}
|
||||
|
||||
String _readPort() =>
|
||||
storage.read("${type.value.name}_port") ?? defaultPort.toString();
|
||||
|
||||
Stream<ServerResult> start() async* {
|
||||
try {
|
||||
if(started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
final hostData = this.host.text.trim();
|
||||
final portData = this.port.text.trim();
|
||||
if(type() != ServerType.local) {
|
||||
started.value = true;
|
||||
yield ServerResult(ServerResultType.starting);
|
||||
}else {
|
||||
started.value = false;
|
||||
if(portData != defaultPort.toString()) {
|
||||
yield ServerResult(ServerResultType.starting);
|
||||
}
|
||||
}
|
||||
|
||||
if (hostData.isEmpty) {
|
||||
yield ServerResult(ServerResultType.missingHostError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (portData.isEmpty) {
|
||||
yield ServerResult(ServerResultType.missingPortError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
final portNumber = int.tryParse(portData);
|
||||
if (portNumber == null) {
|
||||
yield ServerResult(ServerResultType.illegalPortError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((type() != ServerType.local || portData != defaultPort.toString()) && await isPortTaken) {
|
||||
yield ServerResult(ServerResultType.freeingPort);
|
||||
final result = await freePort();
|
||||
yield ServerResult(result ? ServerResultType.freePortSuccess : ServerResultType.freePortError);
|
||||
if(!result) {
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(type()){
|
||||
case ServerType.embedded:
|
||||
final process = await startEmbeddedInternal();
|
||||
final processPid = process.pid;
|
||||
watchProcess(processPid).then((value) {
|
||||
if(started()) {
|
||||
started.value = false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ServerType.remote:
|
||||
yield ServerResult(ServerResultType.pingingRemote);
|
||||
final uriResult = await pingServer(hostData, portNumber);
|
||||
if(uriResult == null) {
|
||||
yield ServerResult(ServerResultType.pingError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
remoteServer = await startRemoteBackendProxy(uriResult);
|
||||
break;
|
||||
case ServerType.local:
|
||||
if(portData != defaultPort.toString()) {
|
||||
localServer = await startRemoteBackendProxy(Uri.parse("http://$defaultHost:$portData"));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.pingingLocal);
|
||||
final uriResult = await pingServer(defaultHost, defaultPort);
|
||||
if(uriResult == null) {
|
||||
yield ServerResult(ServerResultType.pingError);
|
||||
remoteServer?.close(force: true);
|
||||
localServer?.close(force: true);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.startSuccess);
|
||||
}catch(error, stackTrace) {
|
||||
yield ServerResult(
|
||||
ServerResultType.startError,
|
||||
error: error,
|
||||
stackTrace: stackTrace
|
||||
);
|
||||
remoteServer?.close(force: true);
|
||||
localServer?.close(force: true);
|
||||
started.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<ServerResult> stop() async* {
|
||||
if(!started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.stopping);
|
||||
started.value = false;
|
||||
try{
|
||||
switch(type()){
|
||||
case ServerType.embedded:
|
||||
killProcessByPort(defaultPort);
|
||||
break;
|
||||
case ServerType.remote:
|
||||
await remoteServer?.close(force: true);
|
||||
remoteServer = null;
|
||||
break;
|
||||
case ServerType.local:
|
||||
await localServer?.close(force: true);
|
||||
localServer = null;
|
||||
break;
|
||||
}
|
||||
yield ServerResult(ServerResultType.stopSuccess);
|
||||
}catch(error, stackTrace){
|
||||
yield ServerResult(
|
||||
ServerResultType.stopError,
|
||||
error: error,
|
||||
stackTrace: stackTrace
|
||||
);
|
||||
started.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<ServerResult> toggle() async* {
|
||||
if(started()) {
|
||||
yield* stop();
|
||||
}else {
|
||||
yield* start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/main.dart';
|
||||
import 'package:reboot_launcher/src/dialog/abstract/info_bar.dart';
|
||||
import 'package:reboot_launcher/src/util/translations.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:version/version.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
class UpdateController {
|
||||
late final GetStorage _storage;
|
||||
@@ -11,6 +16,7 @@ class UpdateController {
|
||||
late final Rx<UpdateStatus> status;
|
||||
late final Rx<UpdateTimer> timer;
|
||||
late final TextEditingController url;
|
||||
late final RxBool customGameServer;
|
||||
InfoBarEntry? infoBarEntry;
|
||||
Future? _updater;
|
||||
|
||||
@@ -19,25 +25,63 @@ class UpdateController {
|
||||
timestamp = RxnInt(_storage.read("ts"));
|
||||
timestamp.listen((value) => _storage.write("ts", value));
|
||||
var timerIndex = _storage.read("timer");
|
||||
timer = Rx(timerIndex == null ? UpdateTimer.day : UpdateTimer.values.elementAt(timerIndex));
|
||||
timer = Rx(timerIndex == null ? UpdateTimer.hour : UpdateTimer.values.elementAt(timerIndex));
|
||||
timer.listen((value) => _storage.write("timer", value.index));
|
||||
url = TextEditingController(text: _storage.read("update_url") ?? kRebootDownloadUrl);
|
||||
url.addListener(() => _storage.write("update_url", url.text));
|
||||
status = Rx(UpdateStatus.waiting);
|
||||
customGameServer = RxBool(_storage.read("custom_game_server") ?? false);
|
||||
customGameServer.listen((value) => _storage.write("custom_game_server", value));
|
||||
}
|
||||
|
||||
Future<void> update([bool force = false]) async {
|
||||
Future<void> notifyLauncherUpdate() async {
|
||||
if(appVersion == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final pubspecResponse = await http.get(Uri.parse("https://raw.githubusercontent.com/Auties00/reboot_launcher/master/gui/pubspec.yaml"));
|
||||
if(pubspecResponse.statusCode != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
final pubspec = loadYaml(pubspecResponse.body);
|
||||
final latestVersion = Version.parse(pubspec["version"]);
|
||||
if(latestVersion <= appVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
late InfoBarEntry infoBar;
|
||||
infoBar = showInfoBar(
|
||||
translations.updateAvailable(latestVersion.toString()),
|
||||
duration: null,
|
||||
severity: InfoBarSeverity.warning,
|
||||
action: Button(
|
||||
child: Text(translations.updateAvailableAction),
|
||||
onPressed: () {
|
||||
infoBar.close();
|
||||
launchUrl(Uri.parse("https://github.com/Auties00/reboot_launcher/releases"));
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> updateReboot([bool force = false]) async {
|
||||
if(_updater != null) {
|
||||
return await _updater;
|
||||
}
|
||||
|
||||
final result = _update(force);
|
||||
final result = _updateReboot(force);
|
||||
_updater = result;
|
||||
return await result;
|
||||
}
|
||||
|
||||
Future<void> _update([bool force = false]) async {
|
||||
Future<void> _updateReboot([bool force = false]) async {
|
||||
try {
|
||||
if(customGameServer.value) {
|
||||
status.value = UpdateStatus.success;
|
||||
return;
|
||||
}
|
||||
|
||||
final needsUpdate = await hasRebootDllUpdate(
|
||||
timestamp.value,
|
||||
hours: timer.value.hours,
|
||||
@@ -72,7 +116,7 @@ class UpdateController {
|
||||
duration: infoBarLongDuration,
|
||||
severity: InfoBarSeverity.error,
|
||||
action: Button(
|
||||
onPressed: () => update(true),
|
||||
onPressed: () => updateReboot(true),
|
||||
child: Text(translations.downloadDllRetry),
|
||||
)
|
||||
);
|
||||
@@ -86,7 +130,8 @@ class UpdateController {
|
||||
timer.value = UpdateTimer.never;
|
||||
url.text = kRebootDownloadUrl;
|
||||
status.value = UpdateStatus.waiting;
|
||||
update();
|
||||
customGameServer.value = false;
|
||||
updateReboot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user