This commit is contained in:
Alessandro Autiero
2024-06-03 16:26:04 +02:00
parent 3069f3aa05
commit 46034aa1fa
24 changed files with 242 additions and 189 deletions

View File

@@ -26,7 +26,7 @@ class SettingsController extends GetxController {
gameServerDll = _createController("game_server", "reboot.dll");
unrealEngineConsoleDll = _createController("unreal_engine_console", "console.dll");
backendDll = _createController("backend", "cobalt.dll");
memoryLeakDll = _createController("memory_leak", "memoryleak.dll");
memoryLeakDll = _createController("memory_leak", "memoryFix.dll");
gameServerPort = TextEditingController(text: _storage.read("game_server_port") ?? kDefaultGameServerPort);
gameServerPort.addListener(() => _storage.write("game_server_port", gameServerPort.text));
width = _storage.read("width") ?? kDefaultWindowWidth;
@@ -67,5 +67,5 @@ class SettingsController extends GetxController {
firstRun.value = true;
}
String _controllerDefaultPath(String name) => "${assetsDirectory.path}\\dlls\\$name";
String _controllerDefaultPath(String name) => "${dllsDirectory.path}\\$name";
}

View File

@@ -53,6 +53,7 @@ extension ServerControllerDialog on BackendController {
severity: InfoBarSeverity.success
);
case ServerResultType.startError:
print(event.stackTrace);
return showInfoBar(
type.value == ServerType.local ? translations.localServerError(event.error ?? translations.unknownError) : translations.startServerError(event.error ?? translations.unknownError),
severity: InfoBarSeverity.error,

View File

@@ -46,16 +46,26 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
@override
void initState() {
windowManager.addListener(this);
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateController.notifyLauncherUpdate();
_updateController.updateReboot();
watchDlls().listen((filePath) => showDllDeletedDialog(() {
downloadCriticalDllInteractive(filePath);
}));
});
WidgetsBinding.instance.addPostFrameCallback((_) => _checkUpdates());
super.initState();
}
void _checkUpdates() {
_updateController.notifyLauncherUpdate();
if(!dllsDirectory.existsSync()) {
dllsDirectory.createSync(recursive: true);
}
for(final injectable in InjectableDll.values) {
downloadCriticalDllInteractive("${injectable.name}.dll");
}
watchDlls().listen((filePath) => showDllDeletedDialog(() {
downloadCriticalDllInteractive(filePath);
}));
}
@override
void onWindowClose() {
exit(0); // Force closing

View File

@@ -1,15 +1,53 @@
import 'dart:async';
import 'dart:collection';
import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart' hide FluentIcons;
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:reboot_common/common.dart';
import 'package:reboot_launcher/src/controller/settings_controller.dart';
import 'package:reboot_launcher/src/page/abstract/page.dart';
import 'package:reboot_launcher/src/page/abstract/page_type.dart';
import 'package:reboot_launcher/src/page/pages.dart';
import 'package:reboot_launcher/src/util/info.dart';
import 'package:reboot_launcher/src/util/translations.dart';
import 'package:path/path.dart' as path;
import 'package:reboot_launcher/src/widget/info_tile.dart';
class InfoPage extends RebootPage {
static late final List<InfoTile> _infoTiles;
static Object? initInfoTiles() {
try {
final directory = Directory("${assetsDirectory.path}\\info\\$currentLocale");
final map = SplayTreeMap<int, InfoTile>();
for(final entry in directory.listSync()) {
if(entry is File) {
final name = Uri.decodeQueryComponent(path.basename(entry.path));
final splitter = name.indexOf(".");
if(splitter == -1) {
continue;
}
final index = int.tryParse(name.substring(0, splitter));
if(index == null) {
continue;
}
final questionName = Uri.decodeQueryComponent(name.substring(splitter + 2));
map[index] = InfoTile(
title: Text(questionName),
content: Text(entry.readAsStringSync())
);
}
}
_infoTiles = map.values.toList(growable: false);
return null;
}catch(error) {
_infoTiles = [];
return error;
}
}
const InfoPage({Key? key}) : super(key: key);
@override
@@ -30,7 +68,7 @@ class InfoPage extends RebootPage {
class _InfoPageState extends RebootPageState<InfoPage> {
final SettingsController _settingsController = Get.find<SettingsController>();
RxInt _counter = RxInt(180);
RxInt _counter = RxInt(kDebugMode ? 0 : 180);
@override
void initState() {
@@ -48,7 +86,7 @@ class _InfoPageState extends RebootPageState<InfoPage> {
}
@override
List<Widget> get settings => infoTiles;
List<Widget> get settings => InfoPage._infoTiles;
@override
Widget? get button => Obx(() {

View File

@@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
import 'package:reboot_launcher/src/controller/settings_controller.dart';
import 'package:reboot_launcher/src/controller/update_controller.dart';
import 'package:reboot_launcher/src/dialog/abstract/info_bar.dart';
import 'package:reboot_launcher/src/util/translations.dart';
@@ -68,3 +70,26 @@ Future<void> _downloadCriticalDllInteractive(String filePath) async {
_operations.remove(fileName);
}
}
extension InjectableDllExtension on InjectableDll {
String get path {
final SettingsController settingsController = Get.find<SettingsController>();
switch(this){
case InjectableDll.reboot:
if(_updateController.customGameServer.value) {
final file = File(settingsController.gameServerDll.text);
if(file.existsSync()) {
return file.path;
}
}
return rebootDllFile.path;
case InjectableDll.console:
return settingsController.unrealEngineConsoleDll.text;
case InjectableDll.cobalt:
return settingsController.backendDll.text;
case InjectableDll.memoryFix:
return settingsController.memoryLeakDll.text;
}
}
}

View File

@@ -1,41 +0,0 @@
import 'dart:collection';
import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
import 'package:reboot_launcher/src/util/log.dart';
import 'package:reboot_launcher/src/util/translations.dart';
import 'package:reboot_launcher/src/widget/info_tile.dart';
final _entries = SplayTreeMap<int, InfoTile>();
void initInfoTiles() {
try {
final directory = Directory("${assetsDirectory.path}\\info\\$currentLocale");
for(final entry in directory.listSync()) {
if(entry is File) {
final name = Uri.decodeQueryComponent(path.basename(entry.path));
final splitter = name.indexOf(".");
if(splitter == -1) {
continue;
}
final index = int.tryParse(name.substring(0, splitter));
if(index == null) {
continue;
}
final questionName = Uri.decodeQueryComponent(name.substring(splitter + 2));
_entries[index] = InfoTile(
title: Text(questionName),
content: Text(entry.readAsStringSync())
);
}
}
}catch(error) {
log("[INFO] Error occurred while initializing info tiles: $error");
}
}
List<InfoTile> get infoTiles => _entries.values.toList(growable: false);

View File

@@ -103,8 +103,8 @@ class _LaunchButtonState extends State<LaunchButton> {
log("[${widget.host ? 'HOST' : 'GAME'}] Setting started...");
_setStarted(widget.host, true);
log("[${widget.host ? 'HOST' : 'GAME'}] Set started");
log("[${widget.host ? 'HOST' : 'GAME'}] Checking dlls: ${_Injectable.values}");
for (final injectable in _Injectable.values) {
log("[${widget.host ? 'HOST' : 'GAME'}] Checking dlls: ${InjectableDll.values}");
for (final injectable in InjectableDll.values) {
if(await _getDllFileOrStop(injectable, widget.host) == null) {
return;
}
@@ -239,7 +239,7 @@ class _LaunchButtonState extends State<LaunchButton> {
}else{
_gameController.instance.value = instance;
}
await _injectOrShowError(_Injectable.sslBypassV2, host);
await _injectOrShowError(InjectableDll.cobalt, host);
log("[${host ? 'HOST' : 'GAME'}] Finished creating game instance");
return instance;
}
@@ -319,46 +319,33 @@ class _LaunchButtonState extends State<LaunchButton> {
_onStop(
reason: _StopReason.normal
);
return;
}
if(kCorruptedBuildErrors.any((element) => line.contains(element))){
}else if(kCorruptedBuildErrors.any((element) => line.contains(element))){
_onStop(
reason: _StopReason.corruptedVersionError
);
return;
}
if(kCannotConnectErrors.any((element) => line.contains(element))){
}else if(kCannotConnectErrors.any((element) => line.contains(element))){
_onStop(
reason: _StopReason.tokenError
);
return;
}
if(kLoggedInLines.every((entry) => line.contains(entry))) {
}else if(kLoggedInLines.every((entry) => line.contains(entry))) {
final instance = host ? _hostingController.instance.value : _gameController.instance.value;
if(instance != null && !instance.launched) {
instance.launched = true;
instance.tokenError = false;
await _injectOrShowError(_Injectable.memoryFix, host);
await _injectOrShowError(InjectableDll.memoryFix, host);
if(!host){
await _injectOrShowError(_Injectable.console, host);
await _injectOrShowError(InjectableDll.console, host);
_onGameClientInjected();
}else {
final gameServerPort = int.tryParse(_settingsController.gameServerPort.text);
if(gameServerPort != null) {
await killProcessByPort(gameServerPort);
}
await _injectOrShowError(_Injectable.reboot, host);
await _injectOrShowError(InjectableDll.reboot, host);
_onGameServerInjected();
}
}
return;
}
if(line.contains(kGameFinishedLine) && host) {
}else if(line.contains(kGameFinishedLine) && host) {
if(_hostingController.autoRestart.value) {
final notification = LocalNotification(
title: translations.gameServerEnd,
@@ -378,10 +365,7 @@ class _LaunchButtonState extends State<LaunchButton> {
_onStop(reason: _StopReason.normal, host: true);
});
}
return;
}
if(line.contains("Display") && host && virtualDesktop) {
}else if(line.contains(kDisplayInitializedLine) && host && virtualDesktop) {
final hostingInstance = _hostingController.instance.value;
if(hostingInstance != null && !hostingInstance.movedToVirtualDesktop) {
hostingInstance.movedToVirtualDesktop = true;
@@ -615,7 +599,7 @@ class _LaunchButtonState extends State<LaunchButton> {
}
}
Future<void> _injectOrShowError(_Injectable injectable, bool hosting) async {
Future<void> _injectOrShowError(InjectableDll injectable, bool hosting) async {
final instance = hosting ? _hostingController.instance.value : _gameController.instance.value;
if (instance == null) {
log("[${hosting ? 'HOST' : 'GAME'}] No instance found to inject ${injectable.name}");
@@ -637,7 +621,7 @@ class _LaunchButtonState extends State<LaunchButton> {
}
log("[${hosting ? 'HOST' : 'GAME'}] Trying to inject ${injectable.name}...");
await injectDll(gameProcess, dllPath.path);
await injectDll(gameProcess, dllPath);
log("[${hosting ? 'HOST' : 'GAME'}] Injected ${injectable.name}");
} catch (error, stackTrace) {
log("[${hosting ? 'HOST' : 'GAME'}] Cannot inject ${injectable.name}: $error $stackTrace");
@@ -650,29 +634,9 @@ class _LaunchButtonState extends State<LaunchButton> {
}
}
String _getDllPath(_Injectable injectable) {
switch(injectable){
case _Injectable.reboot:
if(_updateController.customGameServer.value) {
final file = File(_settingsController.gameServerDll.text);
if(file.existsSync()) {
return file.path;
}
}
return rebootDllFile.path;
case _Injectable.console:
return _settingsController.unrealEngineConsoleDll.text;
case _Injectable.sslBypassV2:
return _settingsController.backendDll.text;
case _Injectable.memoryFix:
return _settingsController.memoryLeakDll.text;
}
}
Future<File?> _getDllFileOrStop(_Injectable injectable, bool host) async {
Future<File?> _getDllFileOrStop(InjectableDll injectable, bool host) async {
log("[${host ? 'HOST' : 'GAME'}] Checking dll ${injectable}...");
final path = _getDllPath(injectable);
final path = injectable.path;
log("[${host ? 'HOST' : 'GAME'}] Path: $path");
final file = File(path);
if(await file.exists()) {
@@ -712,11 +676,4 @@ enum _StopReason {
exitCode;
bool get isError => name.contains("Error");
}
enum _Injectable {
console,
sslBypassV2,
reboot,
memoryFix,
}
}