mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 19:22:22 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cfa4af236 | ||
|
|
d42946c44b | ||
|
|
0a59a32c1b | ||
|
|
2046cb14f6 | ||
|
|
e3f7a1d2cc | ||
|
|
cd6752ed3f | ||
|
|
e1df46efd9 |
8
archive/README.md
Normal file
8
archive/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Builds Archive
|
||||||
|
|
||||||
|
Builds are stored on a Cloudflare R2 instance at `https://builds.rebootfn.org/versions.json`.
|
||||||
|
If you want to move them to another AWS-compatible object storage, run:
|
||||||
|
```
|
||||||
|
move.ps1
|
||||||
|
```
|
||||||
|
and provide the required parameters.
|
||||||
98
archive/move.ps1
Normal file
98
archive/move.ps1
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$UrlListPath, # Path to a text file with one URL per line
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$BucketName, # Name of the R2 bucket
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$AccessKey, # Your R2 access key
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$SecretKey, # Your R2 secret key
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$EndPointURL, # Your R2 endpoint URL, e.g. https://<account_id>.r2.cloudflarestorage.com
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[int]$MaxConcurrentConnections = 16, # Number of concurrent connections for each file download
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[int]$SplitCount = 16, # Number of segments to split the download into
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]$AwsRegion = "auto" # Region; often "auto" works for R2, but can be set if needed
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set AWS environment variables for this session
|
||||||
|
$Env:AWS_ACCESS_KEY_ID = $AccessKey
|
||||||
|
$Env:AWS_SECRET_ACCESS_KEY = $SecretKey
|
||||||
|
$Env:AWS_REGION = $AwsRegion # If required, or leave as "auto"
|
||||||
|
|
||||||
|
# Read all URLs from file
|
||||||
|
$Urls = Get-Content $UrlListPath | Where-Object { $_ -and $_. Trim() -ne "" }
|
||||||
|
|
||||||
|
# Ensure aria2 is available
|
||||||
|
if (-not (Get-Command aria2c -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Error "aria2c not found in PATH. Please install aria2."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure aws CLI is available
|
||||||
|
if (-not (Get-Command aws -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Error "aws CLI not found in PATH. Please install AWS CLI."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function Process-Url {
|
||||||
|
param(
|
||||||
|
[string]$Url,
|
||||||
|
[string]$BucketName,
|
||||||
|
[string]$EndPointURL,
|
||||||
|
[int]$MaxConcurrentConnections,
|
||||||
|
[int]$SplitCount
|
||||||
|
)
|
||||||
|
|
||||||
|
# Extract the filename from the URL
|
||||||
|
$FileName = Split-Path -Leaf $Url
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Host "Downloading: $Url"
|
||||||
|
|
||||||
|
# Use aria2c to download with multiple connections
|
||||||
|
& aria2c `
|
||||||
|
--max-connection-per-server=$MaxConcurrentConnections `
|
||||||
|
--split=$SplitCount `
|
||||||
|
--out=$FileName `
|
||||||
|
--check-certificate=false `
|
||||||
|
--header="Cookie: _c_t_c=1" `
|
||||||
|
$Url
|
||||||
|
|
||||||
|
if (!(Test-Path $FileName)) {
|
||||||
|
Write-Host "Failed to download $Url"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Uploading $FileName to R2 bucket: $BucketName"
|
||||||
|
& aws s3 cp $FileName "s3://$BucketName/$FileName" --endpoint-url $EndPointURL
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Host "Failed to upload $FileName to R2"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Upload successful. Deleting local file: $FileName"
|
||||||
|
Remove-Item $FileName -Force
|
||||||
|
|
||||||
|
Write-Host "Completed processing of $FileName."
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Host "Error processing $Url"
|
||||||
|
Write-Host $_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Process each URL sequentially here. If you'd like to run multiple URLs in parallel,
|
||||||
|
# you could replace the foreach loop with a ForEach-Object -Parallel block.
|
||||||
|
foreach ($Url in $Urls) {
|
||||||
|
Process-Url -Url $Url -BucketName $BucketName -EndPointURL $EndPointURL -MaxConcurrentConnections $MaxConcurrentConnections -SplitCount $SplitCount
|
||||||
|
}
|
||||||
85
archive/versions.txt
Normal file
85
archive/versions.txt
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
https://builds.rebootfn.org/1.7.2.zip
|
||||||
|
https://builds.rebootfn.org/1.8.rar
|
||||||
|
https://builds.rebootfn.org/1.8.1.rar
|
||||||
|
https://builds.rebootfn.org/1.8.2.rar
|
||||||
|
https://builds.rebootfn.org/1.9.rar
|
||||||
|
https://builds.rebootfn.org/1.9.1.rar
|
||||||
|
https://builds.rebootfn.org/1.10.rar
|
||||||
|
https://builds.rebootfn.org/1.11.zip
|
||||||
|
https://builds.rebootfn.org/2.1.0.zip
|
||||||
|
https://builds.rebootfn.org/2.2.0.rar
|
||||||
|
https://builds.rebootfn.org/2.3.rar
|
||||||
|
https://builds.rebootfn.org/2.4.0.zip
|
||||||
|
https://builds.rebootfn.org/2.4.2.zip
|
||||||
|
https://builds.rebootfn.org/2.5.0.rar
|
||||||
|
https://builds.rebootfn.org/3.0.zip
|
||||||
|
https://builds.rebootfn.org/3.1.rar
|
||||||
|
https://builds.rebootfn.org/3.1.1.zip
|
||||||
|
https://builds.rebootfn.org/3.2.zip
|
||||||
|
https://builds.rebootfn.org/3.3.rar
|
||||||
|
https://builds.rebootfn.org/3.5.rar
|
||||||
|
https://builds.rebootfn.org/3.6.zip
|
||||||
|
https://builds.rebootfn.org/4.0.zip
|
||||||
|
https://builds.rebootfn.org/4.1.zip
|
||||||
|
https://builds.rebootfn.org/4.2.zip
|
||||||
|
https://builds.rebootfn.org/4.4.rar
|
||||||
|
https://builds.rebootfn.org/4.5.rar
|
||||||
|
https://builds.rebootfn.org/5.00.rar
|
||||||
|
https://builds.rebootfn.org/5.0.1.rar
|
||||||
|
https://builds.rebootfn.org/5.10.rar
|
||||||
|
https://builds.rebootfn.org/5.21.rar
|
||||||
|
https://builds.rebootfn.org/5.30.rar
|
||||||
|
https://builds.rebootfn.org/5.40.rar
|
||||||
|
https://builds.rebootfn.org/6.00.rar
|
||||||
|
https://builds.rebootfn.org/6.01.rar
|
||||||
|
https://builds.rebootfn.org/6.1.1.rar
|
||||||
|
https://builds.rebootfn.org/6.02.rar
|
||||||
|
https://builds.rebootfn.org/6.2.1.rar
|
||||||
|
https://builds.rebootfn.org/6.10.rar
|
||||||
|
https://builds.rebootfn.org/6.10.1.rar
|
||||||
|
https://builds.rebootfn.org/6.10.2.rar
|
||||||
|
https://builds.rebootfn.org/6.21.rar
|
||||||
|
https://builds.rebootfn.org/6.22.rar
|
||||||
|
https://builds.rebootfn.org/6.30.rar
|
||||||
|
https://builds.rebootfn.org/6.31.rar
|
||||||
|
https://builds.rebootfn.org/7.00.rar
|
||||||
|
https://builds.rebootfn.org/7.10.rar
|
||||||
|
https://builds.rebootfn.org/7.20.rar
|
||||||
|
https://builds.rebootfn.org/7.30.zip
|
||||||
|
https://builds.rebootfn.org/7.40.rar
|
||||||
|
https://builds.rebootfn.org/8.00.zip
|
||||||
|
https://builds.rebootfn.org/8.20.rar
|
||||||
|
https://builds.rebootfn.org/8.30.rar
|
||||||
|
https://builds.rebootfn.org/8.40.zip
|
||||||
|
https://builds.rebootfn.org/8.50.zip
|
||||||
|
https://builds.rebootfn.org/8.51.rar
|
||||||
|
https://builds.rebootfn.org/9.00.zip
|
||||||
|
https://builds.rebootfn.org/9.01.zip
|
||||||
|
https://builds.rebootfn.org/9.10.rar
|
||||||
|
https://builds.rebootfn.org/9.21.zip
|
||||||
|
https://builds.rebootfn.org/9.30.zip
|
||||||
|
https://builds.rebootfn.org/9.40.zip
|
||||||
|
https://builds.rebootfn.org/9.41.rar
|
||||||
|
https://builds.rebootfn.org/10.00.zip
|
||||||
|
https://builds.rebootfn.org/10.10.zip
|
||||||
|
https://builds.rebootfn.org/10.20.zip
|
||||||
|
https://builds.rebootfn.org/10.31.zip
|
||||||
|
https://builds.rebootfn.org/10.40.rar
|
||||||
|
https://builds.rebootfn.org/11.00.zip
|
||||||
|
https://builds.rebootfn.org/11.31.rar
|
||||||
|
https://builds.rebootfn.org/12.00.rar
|
||||||
|
https://builds.rebootfn.org/12.21.zip
|
||||||
|
https://builds.rebootfn.org/12.50.zip
|
||||||
|
https://builds.rebootfn.org/12.61.zip
|
||||||
|
https://builds.rebootfn.org/13.00.rar
|
||||||
|
https://builds.rebootfn.org/13.40.zip
|
||||||
|
https://builds.rebootfn.org/14.00.rar
|
||||||
|
https://builds.rebootfn.org/14.40.rar
|
||||||
|
https://builds.rebootfn.org/14.60.rar
|
||||||
|
https://builds.rebootfn.org/15.30.rar
|
||||||
|
https://builds.rebootfn.org/16.40.rar
|
||||||
|
https://builds.rebootfn.org/17.30.zip
|
||||||
|
https://builds.rebootfn.org/17.50.zip
|
||||||
|
https://builds.rebootfn.org/18.40.zip
|
||||||
|
https://builds.rebootfn.org/19.10.rar
|
||||||
|
https://builds.rebootfn.org/20.40.zip"
|
||||||
@@ -134,17 +134,13 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _startAriaServer() async {
|
Future<void> _startAriaServer() async {
|
||||||
final running = await _isAriaRunning();
|
await stopDownloadServer();
|
||||||
if(running) {
|
|
||||||
await killProcessByPort(_ariaPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
final aria2c = File("${assetsDirectory.path}\\build\\aria2c.exe");
|
final aria2c = File("${assetsDirectory.path}\\build\\aria2c.exe");
|
||||||
if(!aria2c.existsSync()) {
|
if(!aria2c.existsSync()) {
|
||||||
throw "Missing aria2c.exe";
|
throw "Missing aria2c.exe";
|
||||||
}
|
}
|
||||||
|
|
||||||
await startProcess(
|
final process = await startProcess(
|
||||||
executable: aria2c,
|
executable: aria2c,
|
||||||
args: [
|
args: [
|
||||||
"--max-connection-per-server=${Platform.numberOfProcessors}",
|
"--max-connection-per-server=${Platform.numberOfProcessors}",
|
||||||
@@ -153,10 +149,14 @@ Future<void> _startAriaServer() async {
|
|||||||
"--rpc-listen-all=true",
|
"--rpc-listen-all=true",
|
||||||
"--rpc-allow-origin-all",
|
"--rpc-allow-origin-all",
|
||||||
"--rpc-secret=$_ariaSecret",
|
"--rpc-secret=$_ariaSecret",
|
||||||
"--rpc-listen-port=$_ariaPort"
|
"--rpc-listen-port=$_ariaPort",
|
||||||
|
"--file-allocation=none"
|
||||||
],
|
],
|
||||||
window: false
|
window: false
|
||||||
);
|
);
|
||||||
|
process.stdOutput.listen((message) => log("[ARIA] Message: $message"));
|
||||||
|
process.stdError.listen((error) => log("[ARIA] Error: $error"));
|
||||||
|
process.exitCode.then((exitCode) => log("[ARIA] Exit code: $exitCode"));
|
||||||
for(var i = 0; i < _ariaMaxSpawnTime.inSeconds; i++) {
|
for(var i = 0; i < _ariaMaxSpawnTime.inSeconds; i++) {
|
||||||
if(await _isAriaRunning()) {
|
if(await _isAriaRunning()) {
|
||||||
return;
|
return;
|
||||||
@@ -177,8 +177,8 @@ Future<bool> _isAriaRunning() async {
|
|||||||
"token:${_ariaSecret}"
|
"token:${_ariaSecret}"
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
await http.post(_ariaEndpoint, body: jsonEncode(statusRequest));
|
final response = await http.post(_ariaEndpoint, body: jsonEncode(statusRequest));
|
||||||
return true;
|
return response.statusCode == 200;
|
||||||
}catch(_) {
|
}catch(_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -227,11 +227,16 @@ Future<void> _stopAriaDownload(String downloadId) async {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
await http.post(_ariaEndpoint, body: jsonEncode(addDownloadRequest));
|
await http.post(_ariaEndpoint, body: jsonEncode(addDownloadRequest));
|
||||||
|
stopDownloadServer();
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
throw "Stop failed (${error})";
|
throw "Stop failed (${error})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> stopDownloadServer() async {
|
||||||
|
await killProcessByPort(_ariaPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
|
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
|
||||||
Process? process;
|
Process? process;
|
||||||
|
|||||||
@@ -1,16 +1,39 @@
|
|||||||
# reboot_launcher
|
|
||||||
|
|
||||||
Launcher for project reboot
|
# Reboot Launcher
|
||||||
|
|
||||||
|
Welcome to the **Reboot Launcher**!
|
||||||
|
This is a GUI application developed as part of the **Reboot Project**.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
### Running the Project
|
||||||
|
To launch the project in development mode, simply run:
|
||||||
|
```
|
||||||
|
flutter run
|
||||||
|
```
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
### Building the Project
|
||||||
|
To create a production-ready build, use:
|
||||||
|
```
|
||||||
|
flutter build
|
||||||
|
```
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
### Packaging the Project
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
To package the application for distribution, run:
|
||||||
|
```
|
||||||
|
package.bat
|
||||||
|
```
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
## Requirements
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
- [Flutter SDK](https://flutter.dev/docs/get-started/install)
|
||||||
samples, guidance on mobile development, and a full API reference.
|
- Supported operating systems: Windows
|
||||||
|
|
||||||
|
## Other platforms
|
||||||
|
|
||||||
|
Native support for these platforms is not currently planned, but Linux support is a priority for the 10.0 release cycle
|
||||||
|
|
||||||
|
- [Linux Tutorial using Proton](https://www.reddit.com/r/linux_gaming/comments/1fwa4l8/guide_running_a_fortnite_private_server_to_play/)
|
||||||
|
- No tutorials are available for MacOS(got lost when the Reboot discord was banned), but it's possible to run Reboot using a compatibility layer
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
Contributions are welcome! Feel free to open an issue or submit a pull request.
|
||||||
@@ -216,7 +216,6 @@
|
|||||||
"downloadedVersion": "The download was completed successfully!",
|
"downloadedVersion": "The download was completed successfully!",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"downloading": "Downloading...",
|
"downloading": "Downloading...",
|
||||||
"allocatingSpace": "Allocating disk space...",
|
|
||||||
"startingDownload": "Starting download...",
|
"startingDownload": "Starting download...",
|
||||||
"extracting": "Extracting...",
|
"extracting": "Extracting...",
|
||||||
"buildProgress": "{progress}%",
|
"buildProgress": "{progress}%",
|
||||||
@@ -237,7 +236,7 @@
|
|||||||
"startGame": "Start fortnite",
|
"startGame": "Start fortnite",
|
||||||
"stopGame": "Close fortnite",
|
"stopGame": "Close fortnite",
|
||||||
"waitingForGameServer": "Waiting for the game server to boot up...",
|
"waitingForGameServer": "Waiting for the game server to boot up...",
|
||||||
"gameServerStartWarning": "The game server was started successfully, but Reboot didn't load",
|
"gameServerStartWarning": "Unsupported version: the game server crashed while setting up the server",
|
||||||
"gameServerStartLocalWarning": "The game server was started successfully, but other players can't join",
|
"gameServerStartLocalWarning": "The game server was started successfully, but other players can't join",
|
||||||
"gameServerStarted": "The game server was started successfully",
|
"gameServerStarted": "The game server was started successfully",
|
||||||
"gameClientStarted": "The game client was started successfully",
|
"gameClientStarted": "The game client was started successfully",
|
||||||
|
|||||||
@@ -171,7 +171,8 @@ Future<void> _initWindow() async {
|
|||||||
}else {
|
}else {
|
||||||
await windowManager.setAlignment(Alignment.center);
|
await windowManager.setAlignment(Alignment.center);
|
||||||
}
|
}
|
||||||
|
await windowManager.setPreventClose(true);
|
||||||
|
await windowManager.setResizable(true);
|
||||||
if(isWin11) {
|
if(isWin11) {
|
||||||
await Window.setEffect(
|
await Window.setEffect(
|
||||||
effect: WindowEffect.acrylic,
|
effect: WindowEffect.acrylic,
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import 'package:get/get.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/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:windows_taskbar/windows_taskbar.dart';
|
import 'package:windows_taskbar/windows_taskbar.dart';
|
||||||
|
|
||||||
class AddVersionDialog extends StatefulWidget {
|
class AddVersionDialog extends StatefulWidget {
|
||||||
@@ -35,9 +35,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
final Rxn<double> _progress = Rxn();
|
final Rxn<double> _progress = Rxn();
|
||||||
final RxInt _speed = RxInt(0);
|
final RxInt _speed = RxInt(0);
|
||||||
|
|
||||||
late DiskSpace _diskSpace;
|
|
||||||
late Future<List<FortniteBuild>> _fetchFuture;
|
late Future<List<FortniteBuild>> _fetchFuture;
|
||||||
late Future _diskFuture;
|
|
||||||
|
|
||||||
SendPort? _downloadPort;
|
SendPort? _downloadPort;
|
||||||
Object? _error;
|
Object? _error;
|
||||||
@@ -45,10 +43,10 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_fetchFuture = compute(fetchBuilds, null);
|
_fetchFuture = compute(fetchBuilds, null).then((value) {
|
||||||
_diskSpace = DiskSpace();
|
_updateFormDefaults();
|
||||||
_diskFuture = _diskSpace.scan()
|
return value;
|
||||||
.then((_) => _updateFormDefaults());
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
switch(_status.value){
|
switch(_status.value){
|
||||||
case _DownloadStatus.form:
|
case _DownloadStatus.form:
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: Future.wait([_fetchFuture, _diskFuture]).then((_) async => await _fetchFuture),
|
future: _fetchFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => _onDownloadError(snapshot.error, snapshot.stackTrace));
|
WidgetsBinding.instance.addPostFrameCallback((_) => _onDownloadError(snapshot.error, snapshot.stackTrace));
|
||||||
@@ -244,12 +242,12 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if(_progress.value != null && !_isAllocatingDiskSpace)
|
if(_progress.value != null)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8.0,
|
height: 8.0,
|
||||||
),
|
),
|
||||||
|
|
||||||
if(_progress.value != null && !_isAllocatingDiskSpace)
|
if(_progress.value != null)
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@@ -272,7 +270,7 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ProgressBar(value: _isAllocatingDiskSpace ? null : _progress.value?.toDouble())
|
child: ProgressBar(value: _progress.value?.toDouble())
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@@ -291,15 +289,9 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
return translations.startingDownload;
|
return translations.startingDownload;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_speed.value == 0) {
|
|
||||||
return translations.allocatingSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
return translations.downloading;
|
return translations.downloading;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get _isAllocatingDiskSpace => _status.value == _DownloadStatus.downloading && _speed.value == 0;
|
|
||||||
|
|
||||||
Widget _buildFormBody(List<FortniteBuild> builds) {
|
Widget _buildFormBody(List<FortniteBuild> builds) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@@ -450,16 +442,16 @@ class _AddVersionDialogState extends State<AddVersionDialog> {
|
|||||||
_build.value = null;
|
_build.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_source.value != _BuildSource.local && _diskSpace.disks.isNotEmpty) {
|
final disks = WindowsDisk.available();
|
||||||
await _fetchFuture;
|
if(_source.value != _BuildSource.local && disks.isNotEmpty) {
|
||||||
final bestDisk = _diskSpace.disks
|
final bestDisk = disks.reduce((first, second) => first.freeBytesAvailable > second.freeBytesAvailable ? first : second);
|
||||||
.reduce((first, second) => first.availableSpace > second.availableSpace ? first : second);
|
|
||||||
final build = _build.value;
|
final build = _build.value;
|
||||||
if(build == null){
|
if(build == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final pathText = "${bestDisk.devicePath}\\FortniteBuilds\\${build.version}";
|
print("${bestDisk.path}\\FortniteBuilds\\${build.version}");
|
||||||
|
final pathText = "${bestDisk.path}FortniteBuilds\\${build.version}";
|
||||||
_pathController.text = pathText;
|
_pathController.text = pathText;
|
||||||
_pathController.selection = TextSelection.collapsed(offset: pathText.length);
|
_pathController.selection = TextSelection.collapsed(offset: pathText.length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_launcher/src/controller/backend_controller.dart';
|
import 'package:reboot_launcher/src/controller/backend_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/dll_controller.dart';
|
import 'package:reboot_launcher/src/controller/dll_controller.dart';
|
||||||
|
import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
||||||
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
||||||
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
import 'package:reboot_launcher/src/messenger/abstract/dialog.dart';
|
||||||
@@ -43,6 +44,7 @@ class HomePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepAliveClientMixin {
|
class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepAliveClientMixin {
|
||||||
final BackendController _backendController = Get.find<BackendController>();
|
final BackendController _backendController = Get.find<BackendController>();
|
||||||
|
final GameController _gameController = Get.find<GameController>();
|
||||||
final HostingController _hostingController = Get.find<HostingController>();
|
final HostingController _hostingController = Get.find<HostingController>();
|
||||||
final SettingsController _settingsController = Get.find<SettingsController>();
|
final SettingsController _settingsController = Get.find<SettingsController>();
|
||||||
final DllController _dllController = Get.find<DllController>();
|
final DllController _dllController = Get.find<DllController>();
|
||||||
@@ -160,11 +162,45 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onWindowClose() async {
|
void onWindowClose() async {
|
||||||
|
try {
|
||||||
|
await windowManager.hide();
|
||||||
|
}catch(error) {
|
||||||
|
log("[WINDOW] Cannot hide window: $error");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await _hostingController.discardServer();
|
await _hostingController.discardServer();
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
log("[HOSTING] Cannot discard server: $error");
|
log("[HOSTING] Cannot discard server on exit: $error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(_backendController.started.value) {
|
||||||
|
await _backendController.toggleInteractive();
|
||||||
|
}
|
||||||
|
}catch(error) {
|
||||||
|
log("[BACKEND] Cannot stop backend on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_gameController.instance.value?.kill();
|
||||||
|
}catch(error) {
|
||||||
|
log("[GAME] Cannot stop game on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_hostingController.instance.value?.kill();
|
||||||
|
}catch(error) {
|
||||||
|
log("[HOST] Cannot stop host on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await stopDownloadServer();
|
||||||
|
}catch(error) {
|
||||||
|
log("[ARIA] Cannot stop aria server on exit: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
|
|
||||||
@@ -9,22 +10,24 @@ const Duration _timeout = Duration(seconds: 5);
|
|||||||
Completer<bool> pingGameServerOrTimeout(String address, Duration timeout) {
|
Completer<bool> pingGameServerOrTimeout(String address, Duration timeout) {
|
||||||
final completer = Completer<bool>();
|
final completer = Completer<bool>();
|
||||||
final start = DateTime.now();
|
final start = DateTime.now();
|
||||||
(() async {
|
_pingGameServerOrTimeout(completer, start, timeout, address);
|
||||||
while (!completer.isCompleted && DateTime.now().millisecondsSinceEpoch - start.millisecondsSinceEpoch < timeout.inMilliseconds) {
|
|
||||||
final result = await pingGameServer(address);
|
|
||||||
if(result) {
|
|
||||||
completer.complete(true);
|
|
||||||
}else {
|
|
||||||
await Future.delayed(_timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!completer.isCompleted) {
|
|
||||||
completer.complete(false);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
return completer;
|
return completer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _pingGameServerOrTimeout(Completer<bool> completer, DateTime start, Duration timeout, String address) async {
|
||||||
|
while (!completer.isCompleted && max(DateTime.now().millisecondsSinceEpoch - start.millisecondsSinceEpoch, 0) < timeout.inMilliseconds) {
|
||||||
|
final result = await pingGameServer(address);
|
||||||
|
if(result) {
|
||||||
|
completer.complete(true);
|
||||||
|
}else {
|
||||||
|
await Future.delayed(_timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!completer.isCompleted) {
|
||||||
|
completer.complete(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> pingGameServer(String address) async {
|
Future<bool> pingGameServer(String address) async {
|
||||||
final split = address.split(":");
|
final split = address.split(":");
|
||||||
var hostname = split[0];
|
var hostname = split[0];
|
||||||
|
|||||||
@@ -491,4 +491,58 @@ int _convertToHString(String string) {
|
|||||||
|
|
||||||
extension WindowManagerExtension on WindowManager {
|
extension WindowManagerExtension on WindowManager {
|
||||||
Future<void> maximizeOrRestore() async => await windowManager.isMaximized() ? windowManager.restore() : windowManager.maximize();
|
Future<void> maximizeOrRestore() async => await windowManager.isMaximized() ? windowManager.restore() : windowManager.maximize();
|
||||||
|
}
|
||||||
|
|
||||||
|
class WindowsDisk {
|
||||||
|
static final String _nullTerminator = String.fromCharCode(0);
|
||||||
|
|
||||||
|
final String path;
|
||||||
|
final int freeBytesAvailable;
|
||||||
|
final int totalNumberOfBytes;
|
||||||
|
|
||||||
|
const WindowsDisk._internal(this.path, this.freeBytesAvailable, this.totalNumberOfBytes);
|
||||||
|
|
||||||
|
static List<WindowsDisk> available() {
|
||||||
|
final buffer = malloc.allocate<Utf16>(MAX_PATH);
|
||||||
|
try {
|
||||||
|
final length = GetLogicalDriveStrings(MAX_PATH, buffer);
|
||||||
|
if (length == 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toDartString(length: length)
|
||||||
|
.split(_nullTerminator)
|
||||||
|
.where((drive) => drive.length > 1)
|
||||||
|
.map((driveName) {
|
||||||
|
final freeBytesAvailable = calloc<Uint64>();
|
||||||
|
final totalNumberOfBytes = calloc<Uint64>();
|
||||||
|
final totalNumberOfFreeBytes = calloc<Uint64>();
|
||||||
|
try {
|
||||||
|
GetDiskFreeSpaceEx(
|
||||||
|
driveName.toNativeUtf16(),
|
||||||
|
freeBytesAvailable,
|
||||||
|
totalNumberOfBytes,
|
||||||
|
totalNumberOfFreeBytes
|
||||||
|
);
|
||||||
|
return WindowsDisk._internal(
|
||||||
|
driveName,
|
||||||
|
freeBytesAvailable.value,
|
||||||
|
totalNumberOfBytes.value
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
calloc.free(freeBytesAvailable);
|
||||||
|
calloc.free(totalNumberOfBytes);
|
||||||
|
calloc.free(totalNumberOfFreeBytes);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toList(growable: false);
|
||||||
|
} finally {
|
||||||
|
calloc.free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'WindowsDisk{path: $path, freeBytesAvailable: $freeBytesAvailable, totalNumberOfBytes: $totalNumberOfBytes}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -492,7 +492,7 @@ class _LaunchButtonState extends State<LaunchButton> {
|
|||||||
|
|
||||||
final pingOperation = pingGameServerOrTimeout(
|
final pingOperation = pingGameServerOrTimeout(
|
||||||
"$publicIp:$gameServerPort",
|
"$publicIp:$gameServerPort",
|
||||||
const Duration(days: 365)
|
const Duration(days: 1)
|
||||||
);
|
);
|
||||||
this._pingOperation = pingOperation;
|
this._pingOperation = pingOperation;
|
||||||
_gameServerInfoBar = showRebootInfoBar(
|
_gameServerInfoBar = showRebootInfoBar(
|
||||||
|
|||||||
@@ -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: "10.0.0"
|
version: "10.0.4"
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
@@ -58,7 +58,6 @@ dependencies:
|
|||||||
|
|
||||||
# Storage
|
# Storage
|
||||||
get_storage: ^2.1.1
|
get_storage: ^2.1.1
|
||||||
universal_disk_space: ^0.2.3
|
|
||||||
path: ^1.9.0
|
path: ^1.9.0
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ Source: "{{SOURCE_DIR}}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdir
|
|||||||
Source: "..\..\dependencies\redist\VC_redist.x64.exe"; DestDir: {tmp}; Flags: dontcopy
|
Source: "..\..\dependencies\redist\VC_redist.x64.exe"; DestDir: {tmp}; Flags: dontcopy
|
||||||
|
|
||||||
[Run]
|
[Run]
|
||||||
Filename: "powershell.exe"; Parameters: "-ExecutionPolicy Bypass -Command ""Add-MpPreference -ExclusionPath '{app}'"""; Flags: runhidden
|
|
||||||
Filename: "{app}\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: runascurrentuser nowait postinstall skipifsilent
|
Filename: "{app}\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: runascurrentuser nowait postinstall skipifsilent
|
||||||
Filename: "{tmp}\VC_redist.x64.exe"; StatusMsg: "{cm:InstallingVC2017redist}"; Parameters: "/quiet"; Check: VC2017RedistNeedsInstall; Flags: waituntilterminated
|
Filename: "{tmp}\VC_redist.x64.exe"; StatusMsg: "{cm:InstallingVC2017redist}"; Parameters: "/quiet"; Check: VC2017RedistNeedsInstall; Flags: waituntilterminated
|
||||||
|
|
||||||
@@ -46,6 +45,44 @@ Name: "{autodesktop}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; T
|
|||||||
Name: "{userstartup}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup
|
Name: "{userstartup}\{{DISPLAY_NAME}}"; Filename: "{app}\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup
|
||||||
|
|
||||||
[Code]
|
[Code]
|
||||||
|
var
|
||||||
|
Page: TInputOptionWizardPage;
|
||||||
|
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
Page := CreateInputOptionPage(
|
||||||
|
wpWelcome,
|
||||||
|
' Allow DLL injection',
|
||||||
|
' The Reboot Launcher needs to inject DLLs into Fortnite to create the game server',
|
||||||
|
'Selecting the option below will add the Reboot Launcher to the Windows Exclusions list. ' +
|
||||||
|
'This is necessary because DLL injection is often detected as a virus, but is necessary to modify Fortnite. ' +
|
||||||
|
'This option was designed for advanced users who want to manually manage the exclusions list on their machine. ' +
|
||||||
|
'If you do not trust the Reboot Launcher, you can audit the source code at https://github.com/Auties00/reboot_launcher and build it from source.',
|
||||||
|
False,
|
||||||
|
False
|
||||||
|
);
|
||||||
|
Page.Add('&Add the launcher to the Windows Exclusions list');
|
||||||
|
Page.Values[0] := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ShouldSkipPage(PageID: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
var
|
||||||
|
ResultCode: Integer;
|
||||||
|
InstallationDir: String;
|
||||||
|
begin
|
||||||
|
if (CurStep = ssPostInstall) and Page.Values[0] then
|
||||||
|
begin
|
||||||
|
InstallationDir := ExpandConstant('{app}');
|
||||||
|
Exec('powershell.exe', '-ExecutionPolicy Bypass -Command ""Add-MpPreference -ExclusionPath ''' + InstallationDir + '''""' , '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||||
|
Log('Powershell exit code: ' + IntToStr(ResultCode));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function CompareVersion(version1, version2: String): Integer;
|
function CompareVersion(version1, version2: String): Integer;
|
||||||
var
|
var
|
||||||
packVersion1, packVersion2: Int64;
|
packVersion1, packVersion2: Int64;
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Constants
|
|
||||||
{
|
|
||||||
constexpr auto API_URL = L"http://localhost:3551";
|
|
||||||
|
|
||||||
constexpr auto ProcessRequest = L"Could not set libcurl options for easy handle, processing HTTP request failed. Increase verbosity for additional information.";
|
|
||||||
constexpr auto ProcessRequest_C2 = L"STAT_FCurlHttpRequest_ProcessRequest";
|
|
||||||
constexpr auto URLOffset = L"ProcessRequest failed. URL '%s' is not a valid HTTP request. %p";
|
|
||||||
constexpr auto Realloc = L"AbilitySystem.Debug.NextTarget";
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#include "Core.h"
|
|
||||||
|
|
||||||
void Core::Init()
|
|
||||||
{
|
|
||||||
FMemory::_Realloc = Memcury::Scanner::FindStringRef(Constants::Realloc)
|
|
||||||
.ScanFor({ Memcury::ASM::MNEMONIC::CALL })
|
|
||||||
.RelativeOffset(1)
|
|
||||||
.GetAs<decltype(FMemory::_Realloc)>();
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "..\Utilities\memcury.h"
|
|
||||||
|
|
||||||
#include "Constants.h"
|
|
||||||
|
|
||||||
#include "Unreal\Memory.h"
|
|
||||||
#include "Unreal\Array.h"
|
|
||||||
#include "Unreal\String.h"
|
|
||||||
|
|
||||||
namespace Core
|
|
||||||
{
|
|
||||||
void Init();
|
|
||||||
}
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <functional>
|
|
||||||
#include "Memory.h"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class TArray
|
|
||||||
{
|
|
||||||
friend class FString;
|
|
||||||
|
|
||||||
T* Data;
|
|
||||||
int32_t NumElements;
|
|
||||||
int32_t MaxElements;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
inline TArray()
|
|
||||||
{
|
|
||||||
Data = nullptr;
|
|
||||||
NumElements = 0;
|
|
||||||
MaxElements = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void Free()
|
|
||||||
{
|
|
||||||
FMemory::Free(Data);
|
|
||||||
Data = nullptr;
|
|
||||||
NumElements = 0;
|
|
||||||
MaxElements = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Reset()
|
|
||||||
{
|
|
||||||
Free();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline auto GetData()
|
|
||||||
{
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int GetCount() const
|
|
||||||
{
|
|
||||||
return NumElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Num() const
|
|
||||||
{
|
|
||||||
return NumElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline auto& Get(const int Index)
|
|
||||||
{
|
|
||||||
return Data[Index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline auto& First()
|
|
||||||
{
|
|
||||||
return Get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline auto GetRef(const int Index, int Size = sizeof(T))
|
|
||||||
{
|
|
||||||
return (T*)((uint8_t*)Data + (Index * Size));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T& operator[](int i)
|
|
||||||
{
|
|
||||||
return Get(i);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline const T& operator[](int i) const
|
|
||||||
{
|
|
||||||
return Get(i);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool Remove(const int Index, int Size = sizeof(T))
|
|
||||||
{
|
|
||||||
if (Index < NumElements)
|
|
||||||
{
|
|
||||||
if (Index != NumElements - 1)
|
|
||||||
Get(Index) = Get(NumElements - 1);
|
|
||||||
|
|
||||||
--NumElements;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool Any(std::function<bool(T)> Func)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NumElements; ++i)
|
|
||||||
{
|
|
||||||
if (Func(Get(i)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T Select(std::function<bool(T)> Func)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NumElements; ++i)
|
|
||||||
{
|
|
||||||
if (Func(Get(i)))
|
|
||||||
return Get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ForEach(std::function<void(T)> Func)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NumElements; ++i)
|
|
||||||
{
|
|
||||||
Func(Get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Count(std::function<bool(T)> Func)
|
|
||||||
{
|
|
||||||
int Num = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < NumElements; ++i)
|
|
||||||
{
|
|
||||||
if (Func(Get(i)))
|
|
||||||
Num++;
|
|
||||||
}
|
|
||||||
return Num;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Find(const T& Item)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NumElements; i++)
|
|
||||||
{
|
|
||||||
if (this->operator[](i) == Item)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
class FMemory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static inline void* (*_Realloc)(void*, size_t, int64_t);
|
|
||||||
|
|
||||||
static void Free(void* Data)
|
|
||||||
{
|
|
||||||
_Realloc(Data, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Malloc(size_t Size)
|
|
||||||
{
|
|
||||||
return _Realloc(0, Size, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Realloc(void* Data, size_t NewSize)
|
|
||||||
{
|
|
||||||
return _Realloc(Data, NewSize, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Memmove(void* Dest, const void* Src, size_t Count)
|
|
||||||
{
|
|
||||||
return memmove(Dest, Src, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int Memcmp(const void* Buf1, const void* Buf2, size_t Count)
|
|
||||||
{
|
|
||||||
return memcmp(Buf1, Buf2, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Memset(void* Dest, uint8_t Char, size_t Count)
|
|
||||||
{
|
|
||||||
return memset(Dest, Char, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T >
|
|
||||||
static void Memset(T& Src, uint8_t ValueToSet)
|
|
||||||
{
|
|
||||||
Memset(&Src, ValueToSet, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Memzero(void* Dest, size_t Count)
|
|
||||||
{
|
|
||||||
return ZeroMemory(Dest, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void Memzero(T& Src)
|
|
||||||
{
|
|
||||||
Memzero(&Src, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Memcpy(void* Dest, const void* Src, size_t Count)
|
|
||||||
{
|
|
||||||
return memcpy(Dest, Src, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void Memcpy(T& Dest, const T& Src)
|
|
||||||
{
|
|
||||||
Memcpy(&Dest, &Src, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* Calloc(size_t NumElements, size_t ElementSize)
|
|
||||||
{
|
|
||||||
auto TotalSize = NumElements * ElementSize;
|
|
||||||
auto Data = FMemory::Malloc(TotalSize);
|
|
||||||
|
|
||||||
if (!Data)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
FMemory::Memzero(Data, TotalSize);
|
|
||||||
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* Strdup(const char* Str)
|
|
||||||
{
|
|
||||||
auto StrLen = strlen(Str) + 1;
|
|
||||||
auto StrDup = (char*)FMemory::Malloc(StrLen);
|
|
||||||
|
|
||||||
FMemory::Memcpy(StrDup, Str, StrLen);
|
|
||||||
|
|
||||||
return StrDup;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "Array.h"
|
|
||||||
#include "Memory.h"
|
|
||||||
|
|
||||||
class FString : private TArray<wchar_t>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
inline FString()
|
|
||||||
{
|
|
||||||
Data = nullptr;
|
|
||||||
NumElements = 0;
|
|
||||||
MaxElements = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline FString(const char* Other)
|
|
||||||
{
|
|
||||||
if (Other)
|
|
||||||
{
|
|
||||||
auto NumCharacters = (int)std::strlen(Other);
|
|
||||||
MaxElements = NumElements = NumCharacters + 1;
|
|
||||||
|
|
||||||
Data = static_cast<wchar_t*>(FMemory::Malloc(NumElements * sizeof(wchar_t)));
|
|
||||||
|
|
||||||
size_t ConvertedChars = 0;
|
|
||||||
mbstowcs_s(&ConvertedChars, Data, NumElements, Other, _TRUNCATE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaxElements = NumElements = 0;
|
|
||||||
Data = nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline FString(const wchar_t* Other)
|
|
||||||
{
|
|
||||||
MaxElements = NumElements = *Other ? (int)std::wcslen(Other) + 1 : 0;
|
|
||||||
|
|
||||||
if (NumElements && Other)
|
|
||||||
{
|
|
||||||
Data = static_cast<wchar_t*>(FMemory::Malloc(NumElements * 2));
|
|
||||||
|
|
||||||
memcpy_s(Data, NumElements * 2, Other, NumElements * 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline auto c_str()
|
|
||||||
{
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#include "framework.h"
|
|
||||||
|
|
||||||
static void Main()
|
|
||||||
{
|
|
||||||
Sleep(7500);
|
|
||||||
|
|
||||||
Core::Init();
|
|
||||||
Sinum::Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DllMain(HMODULE hModule, DWORD dwReason, void* lpReserved)
|
|
||||||
{
|
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
|
||||||
{
|
|
||||||
Windows::Thread::Create(Main);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Sinum Windows
|
|
||||||
|
|
||||||
https://github.com/projectnovafn/Sinum/tree/main/Windows
|
|
||||||
|
|
||||||
Modified to point to http://localhost:3551
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
|
||||||
VisualStudioVersion = 17.7.34031.279
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sinum", "Sinum.vcxproj", "{E7291B57-1B5B-497C-9C2E-C78A556A06CF}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{E7291B57-1B5B-497C-9C2E-C78A556A06CF}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{E7291B57-1B5B-497C-9C2E-C78A556A06CF}.Release|x64.Build.0 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {7975A2E1-0078-4AF8-AB10-0A71112857A5}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<VCProjectVersion>17.0</VCProjectVersion>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<ProjectGuid>{e7291b57-1b5b-497c-9c2e-c78a556a06cf}</ProjectGuid>
|
|
||||||
<RootNamespace>Sinum</RootNamespace>
|
|
||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;SINUM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>true</ConformanceMode>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableUAC>false</EnableUAC>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;SINUM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>true</ConformanceMode>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableUAC>false</EnableUAC>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>_DEBUG;SINUM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>true</ConformanceMode>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableUAC>false</EnableUAC>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>NDEBUG;SINUM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>true</ConformanceMode>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<EnableUAC>false</EnableUAC>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="Core\Constants.h" />
|
|
||||||
<ClInclude Include="Core\Unreal\Array.h" />
|
|
||||||
<ClInclude Include="Core\Core.h" />
|
|
||||||
<ClInclude Include="Core\Unreal\Memory.h" />
|
|
||||||
<ClInclude Include="Core\Unreal\String.h" />
|
|
||||||
<ClInclude Include="framework.h" />
|
|
||||||
<ClInclude Include="Sinum\Sinum.h" />
|
|
||||||
<ClInclude Include="Utilities\memcury.h" />
|
|
||||||
<ClInclude Include="Utilities\Windows.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="Core\Core.cpp" />
|
|
||||||
<ClCompile Include="Main.cpp" />
|
|
||||||
<ClCompile Include="Sinum\Sinum.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets" />
|
|
||||||
</Project>
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="framework.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Utilities\Windows.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Core\Unreal\Array.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Core\Constants.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Core\Unreal\String.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Core\Unreal\Memory.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Core\Core.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Sinum\Sinum.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Utilities\memcury.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="Main.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Sinum\Sinum.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Core\Core.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup />
|
|
||||||
</Project>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#include "Sinum.h"
|
|
||||||
|
|
||||||
bool Sinum::ProcessRequestHook(FCurlHttpRequest* Request)
|
|
||||||
{
|
|
||||||
std::wstring URL(Request->GetURL().c_str());
|
|
||||||
size_t PathIndex = URL.find(L"ol.epicgames.com");
|
|
||||||
|
|
||||||
if (PathIndex != std::wstring::npos)
|
|
||||||
{
|
|
||||||
auto Path = URL.substr(PathIndex + 16);
|
|
||||||
auto NewURL = Constants::API_URL + Path;
|
|
||||||
|
|
||||||
Request->SetURL(NewURL.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return _ProcessRequest(Request);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sinum::Init()
|
|
||||||
{
|
|
||||||
auto StringRef = Memcury::Scanner::FindStringRef(Constants::ProcessRequest);
|
|
||||||
if (StringRef.IsValid())
|
|
||||||
{
|
|
||||||
_ProcessRequest = StringRef
|
|
||||||
.ScanFor({ 0x48, 0x81, 0xEC }, false)
|
|
||||||
.ScanFor({ 0x40 }, false)
|
|
||||||
.GetAs<decltype(_ProcessRequest)>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_ProcessRequest = Memcury::Scanner::FindStringRef(Constants::ProcessRequest_C2)
|
|
||||||
.ScanFor({ 0x4C, 0x8B, 0xDC }, false)
|
|
||||||
.GetAs<decltype(_ProcessRequest)>();
|
|
||||||
}
|
|
||||||
|
|
||||||
*Memcury::Scanner::FindPointerRef(_ProcessRequest)
|
|
||||||
.GetAs<void**>() = ProcessRequestHook;
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "../framework.h"
|
|
||||||
|
|
||||||
class FCurlHttpRequest
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
void** VTable;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
FString GetURL()
|
|
||||||
{
|
|
||||||
FString Result;
|
|
||||||
return ((FString& (*)(FCurlHttpRequest*, FString&))(*VTable))(this, Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetURL(FString URL)
|
|
||||||
{
|
|
||||||
((void (*)(FCurlHttpRequest*, FString&))(VTable[10]))(this, URL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Sinum
|
|
||||||
{
|
|
||||||
static bool (*_ProcessRequest)(FCurlHttpRequest*);
|
|
||||||
static bool ProcessRequestHook(FCurlHttpRequest* Request);
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "../framework.h"
|
|
||||||
|
|
||||||
namespace Windows
|
|
||||||
{
|
|
||||||
namespace Thread
|
|
||||||
{
|
|
||||||
static HANDLE Create(void* Routine, void* Param = NULL)
|
|
||||||
{
|
|
||||||
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Routine, Param, 0, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
|||||||
// Copyright (c) 2024 Project Nova LLC
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#include "Utilities\memcury.h"
|
|
||||||
#include "Utilities\Windows.h"
|
|
||||||
|
|
||||||
#include "Core\Core.h"
|
|
||||||
#include "Sinum\Sinum.h"
|
|
||||||
Reference in New Issue
Block a user