mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 03:02:22 +01:00
<feat: New release>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||
|
||||
@@ -21,4 +23,10 @@ class AuthenticatorController extends ServerController {
|
||||
|
||||
@override
|
||||
Future<bool> freePort() => freeAuthenticatorPort();
|
||||
|
||||
@override
|
||||
Future<int> startEmbeddedInternal() => startEmbeddedAuthenticator(detached.value);
|
||||
|
||||
@override
|
||||
Future<Uri?> pingServer(String host, String port) => pingAuthenticator(host, port);
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart' hide showDialog;
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:supabase/src/supabase_stream_builder.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
@@ -47,7 +49,7 @@ class GameController extends GetxController {
|
||||
servers = Rxn();
|
||||
supabase.from('hosts')
|
||||
.stream(primaryKey: ['id'])
|
||||
.map((event) => event.where((element) => element["ip"] != null).toSet())
|
||||
.map((event) => _parseValidServers(event))
|
||||
.listen((event) {
|
||||
if(servers.value == null) {
|
||||
servers.value = event;
|
||||
@@ -57,9 +59,17 @@ class GameController extends GetxController {
|
||||
});
|
||||
var serializedInstance = _storage.read("instance");
|
||||
instance = Rxn(serializedInstance != null ? GameInstance.fromJson(jsonDecode(serializedInstance)) : null);
|
||||
instance.listen((value) => _storage.write("instance", jsonEncode(value?.toJson())));
|
||||
instance.listen((_) => saveInstance());
|
||||
}
|
||||
|
||||
Set<Map<String, dynamic>> _parseValidServers(SupabaseStreamEvent event) => event.where((element) => _isValidServer(element)).toSet();
|
||||
|
||||
bool _isValidServer(Map<String, dynamic> element) =>
|
||||
(kDebugMode || element["id"] != uuid) && element["ip"] != null;
|
||||
|
||||
Future<void> saveInstance() =>
|
||||
_storage.write("instance", jsonEncode(instance.value?.toJson()));
|
||||
|
||||
void reset() {
|
||||
username.text = kDefaultPlayerName;
|
||||
password.text = "";
|
||||
@@ -116,7 +126,6 @@ class GameController extends GetxController {
|
||||
|
||||
Map<String, dynamic>? findServerById(String uuid) {
|
||||
try {
|
||||
print(uuid);
|
||||
return servers.value?.firstWhere((element) => element["id"] == uuid);
|
||||
} on StateError catch(_) {
|
||||
return null;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart' hide showDialog;
|
||||
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/util/watch.dart';
|
||||
|
||||
const String kDefaultServerName = "Reboot Game Server";
|
||||
const String kDefaultDescription = "Just another server";
|
||||
@@ -32,9 +33,11 @@ class HostingController extends GetxController {
|
||||
showPassword = RxBool(false);
|
||||
var serializedInstance = _storage.read("instance");
|
||||
instance = Rxn(serializedInstance != null ? GameInstance.fromJson(jsonDecode(serializedInstance)) : null);
|
||||
instance.listen((value) => _storage.write("instance", jsonEncode(value?.toJson())));
|
||||
instance.listen((_) => saveInstance());
|
||||
}
|
||||
|
||||
Future<void> saveInstance() => _storage.write("instance", jsonEncode(instance.value?.toJson()));
|
||||
|
||||
void reset() {
|
||||
name.text = kDefaultServerName;
|
||||
description.text = kDefaultDescription;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart' hide showDialog;
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/server_controller.dart';
|
||||
|
||||
@@ -7,7 +7,11 @@ class MatchmakerController extends ServerController {
|
||||
|
||||
MatchmakerController() : super() {
|
||||
gameServerAddress = TextEditingController(text: storage.read("game_server_address") ?? kDefaultMatchmakerHost);
|
||||
gameServerAddress.addListener(() => storage.write("game_server_address", gameServerAddress.text));
|
||||
writeMatchmakingIp(gameServerAddress.text);
|
||||
gameServerAddress.addListener(() {
|
||||
storage.write("game_server_address", gameServerAddress.text);
|
||||
writeMatchmakingIp(gameServerAddress.text);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -27,4 +31,10 @@ class MatchmakerController extends ServerController {
|
||||
|
||||
@override
|
||||
Future<bool> freePort() => freeMatchmakerPort();
|
||||
|
||||
@override
|
||||
Future<int> startEmbeddedInternal() => startEmbeddedMatchmaker(detached.value);
|
||||
|
||||
@override
|
||||
Future<Uri?> pingServer(String host, String port) => pingMatchmaker(host, port);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart' hide showDialog;
|
||||
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';
|
||||
@@ -15,7 +15,7 @@ abstract class ServerController extends GetxController {
|
||||
late final Semaphore semaphore;
|
||||
late RxBool started;
|
||||
late RxBool detached;
|
||||
Process? embeddedServer;
|
||||
int? embeddedServerPid;
|
||||
HttpServer? localServer;
|
||||
HttpServer? remoteServer;
|
||||
|
||||
@@ -52,12 +52,17 @@ abstract class ServerController extends GetxController {
|
||||
|
||||
String get defaultPort;
|
||||
|
||||
Future<Uri?> pingServer(String host, String port);
|
||||
|
||||
Future<bool> get isPortFree;
|
||||
|
||||
Future<bool> get isPortTaken async => !(await isPortFree);
|
||||
|
||||
Future<bool> freePort();
|
||||
|
||||
@protected
|
||||
Future<int> startEmbeddedInternal();
|
||||
|
||||
void reset() async {
|
||||
type.value = ServerType.values.elementAt(0);
|
||||
for (var type in ServerType.values) {
|
||||
@@ -80,22 +85,31 @@ abstract class ServerController extends GetxController {
|
||||
storage.read("${type.value.name}_port") ?? defaultPort;
|
||||
|
||||
Stream<ServerResult> start() async* {
|
||||
if(started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.starting);
|
||||
started.value = true;
|
||||
try {
|
||||
var host = this.host.text.trim();
|
||||
if (host.isEmpty) {
|
||||
yield ServerResult(ServerResultType.missingHostError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var port = this.port.text.trim();
|
||||
if (port.isEmpty) {
|
||||
yield ServerResult(ServerResultType.missingPortError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var portNumber = int.tryParse(port);
|
||||
if (portNumber == null) {
|
||||
yield ServerResult(ServerResultType.illegalPortError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,18 +118,20 @@ abstract class ServerController extends GetxController {
|
||||
var result = await freePort();
|
||||
yield ServerResult(result ? ServerResultType.freePortSuccess : ServerResultType.freePortError);
|
||||
if(!result) {
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch(type()){
|
||||
case ServerType.embedded:
|
||||
embeddedServer = await startEmbeddedAuthenticator(detached());
|
||||
embeddedServerPid = await startEmbeddedInternal();
|
||||
break;
|
||||
case ServerType.remote:
|
||||
yield ServerResult(ServerResultType.pingingRemote);
|
||||
var uriResult = await ping(host, port);
|
||||
var uriResult = await pingServer(host, port);
|
||||
if(uriResult == null) {
|
||||
yield ServerResult(ServerResultType.pingError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -130,29 +146,35 @@ abstract class ServerController extends GetxController {
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.pingingLocal);
|
||||
var uriResult = await pingSelf(defaultPort);
|
||||
var uriResult = await pingServer(defaultHost, defaultPort);
|
||||
if(uriResult == null) {
|
||||
yield ServerResult(ServerResultType.pingError);
|
||||
started.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.startSuccess);
|
||||
started.value = true;
|
||||
}catch(error, stackTrace) {
|
||||
yield ServerResult(
|
||||
ServerResultType.startError,
|
||||
error: error,
|
||||
stackTrace: stackTrace
|
||||
);
|
||||
started.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> stop() async {
|
||||
Stream<ServerResult> stop() async* {
|
||||
if(!started.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield ServerResult(ServerResultType.stopping);
|
||||
started.value = false;
|
||||
try{
|
||||
switch(type()){
|
||||
case ServerType.embedded:
|
||||
freePort();
|
||||
Process.killPid(embeddedServerPid!, ProcessSignal.sigabrt);
|
||||
break;
|
||||
case ServerType.remote:
|
||||
await remoteServer?.close(force: true);
|
||||
@@ -163,17 +185,21 @@ abstract class ServerController extends GetxController {
|
||||
localServer = null;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}catch(_){
|
||||
yield ServerResult(ServerResultType.stopSuccess);
|
||||
}catch(error, stackTrace){
|
||||
yield ServerResult(
|
||||
ServerResultType.stopError,
|
||||
error: error,
|
||||
stackTrace: stackTrace
|
||||
);
|
||||
started.value = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<ServerResult> restart() async* {
|
||||
await resetWinNat();
|
||||
if(started()) {
|
||||
await stop();
|
||||
yield* stop();
|
||||
}
|
||||
|
||||
yield* start();
|
||||
@@ -181,7 +207,7 @@ abstract class ServerController extends GetxController {
|
||||
|
||||
Stream<ServerResult> toggle() async* {
|
||||
if(started()) {
|
||||
await stop();
|
||||
yield* stop();
|
||||
}else {
|
||||
yield* start();
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart' hide showDialog;
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:reboot_launcher/main.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
class SettingsController extends GetxController {
|
||||
static const String _kDefaultIp = "127.0.0.1";
|
||||
|
||||
late final GetStorage _storage;
|
||||
late final String originalDll;
|
||||
late final TextEditingController rebootDll;
|
||||
late final TextEditingController consoleDll;
|
||||
late final TextEditingController authDll;
|
||||
late final TextEditingController gameServerDll;
|
||||
late final TextEditingController unrealEngineConsoleDll;
|
||||
late final TextEditingController authenticatorDll;
|
||||
late final TextEditingController gameServerPort;
|
||||
late final RxBool firstRun;
|
||||
late double width;
|
||||
late double height;
|
||||
@@ -22,9 +20,11 @@ class SettingsController extends GetxController {
|
||||
|
||||
SettingsController() {
|
||||
_storage = GetStorage("reboot_settings");
|
||||
rebootDll = _createController("reboot", "reboot.dll");
|
||||
consoleDll = _createController("console", "console.dll");
|
||||
authDll = _createController("cobalt", "cobalt.dll");
|
||||
gameServerDll = _createController("game_server", "reboot.dll");
|
||||
unrealEngineConsoleDll = _createController("unreal_engine_console", "console.dll");
|
||||
authenticatorDll = _createController("authenticator", "cobalt.dll");
|
||||
gameServerPort = TextEditingController(text: _storage.read("game_server_port") ?? kDefaultGameServerPort);
|
||||
gameServerPort.addListener(() => _storage.write("game_server_port", gameServerPort.text));
|
||||
width = _storage.read("width") ?? kDefaultWindowWidth;
|
||||
height = _storage.read("height") ?? kDefaultWindowHeight;
|
||||
offsetX = _storage.read("offset_x");
|
||||
@@ -40,8 +40,7 @@ class SettingsController extends GetxController {
|
||||
return controller;
|
||||
}
|
||||
|
||||
void saveWindowSize() async {
|
||||
var size = await windowManager.getSize();
|
||||
void saveWindowSize(Size size) {
|
||||
_storage.write("width", size.width);
|
||||
_storage.write("height", size.height);
|
||||
}
|
||||
@@ -52,11 +51,10 @@ class SettingsController extends GetxController {
|
||||
}
|
||||
|
||||
void reset(){
|
||||
rebootDll.text = _controllerDefaultPath("reboot.dll");
|
||||
consoleDll.text = _controllerDefaultPath("console.dll");
|
||||
authDll.text = _controllerDefaultPath("cobalt.dll");
|
||||
gameServerDll.text = _controllerDefaultPath("reboot.dll");
|
||||
unrealEngineConsoleDll.text = _controllerDefaultPath("console.dll");
|
||||
authenticatorDll.text = _controllerDefaultPath("cobalt.dll");
|
||||
firstRun.value = true;
|
||||
writeMatchmakingIp(_kDefaultIp);
|
||||
}
|
||||
|
||||
String _controllerDefaultPath(String name) => "${assetsDirectory.path}\\dlls\\$name";
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart' hide showDialog;
|
||||
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/dialog/abstract/info_bar.dart';
|
||||
|
||||
class UpdateController {
|
||||
late final GetStorage _storage;
|
||||
@@ -22,18 +23,44 @@ class UpdateController {
|
||||
status = Rx(UpdateStatus.waiting);
|
||||
}
|
||||
|
||||
Future<void> update() async {
|
||||
Future<void> update([bool force = false]) async {
|
||||
if(timer.value == UpdateTimer.never) {
|
||||
status.value = UpdateStatus.success;
|
||||
return;
|
||||
}
|
||||
|
||||
showInfoBar(
|
||||
"Downloading reboot dll...",
|
||||
loading: true,
|
||||
duration: null
|
||||
);
|
||||
try {
|
||||
timestamp.value = await downloadRebootDll(url.text, timestamp.value);
|
||||
timestamp.value = await downloadRebootDll(
|
||||
url.text,
|
||||
timestamp.value,
|
||||
hours: timer.value.hours,
|
||||
force: force
|
||||
);
|
||||
status.value = UpdateStatus.success;
|
||||
}catch(_) {
|
||||
showInfoBar(
|
||||
"The reboot dll was downloaded successfully",
|
||||
severity: InfoBarSeverity.success,
|
||||
duration: snackbarShortDuration
|
||||
);
|
||||
}catch(message) {
|
||||
var error = message.toString();
|
||||
error = error.contains(": ") ? error.substring(error.indexOf(": ") + 2) : error;
|
||||
error = error.toLowerCase();
|
||||
status.value = UpdateStatus.error;
|
||||
rethrow;
|
||||
showInfoBar(
|
||||
"An error occurred while downloading the reboot dll: $error",
|
||||
duration: snackbarLongDuration,
|
||||
severity: InfoBarSeverity.error,
|
||||
action: Button(
|
||||
onPressed: () => update(true),
|
||||
child: const Text("Retry"),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +71,19 @@ class UpdateController {
|
||||
status.value = UpdateStatus.waiting;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
extension _UpdateTimerExtension on UpdateTimer {
|
||||
int get hours {
|
||||
switch(this) {
|
||||
case UpdateTimer.never:
|
||||
return -1;
|
||||
case UpdateTimer.hour:
|
||||
return 1;
|
||||
case UpdateTimer.day:
|
||||
return 24;
|
||||
case UpdateTimer.week:
|
||||
return 24 * 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user