This commit is contained in:
Alessandro Autiero
2024-05-20 17:24:00 +02:00
parent 7c2caed16c
commit 9f5590d41c
562 changed files with 3303 additions and 156787 deletions

View File

@@ -5,7 +5,6 @@ import 'package:reboot_cli/src/game.dart';
import 'package:reboot_cli/src/reboot.dart';
import 'package:reboot_cli/src/server.dart';
import 'package:reboot_common/common.dart';
import 'package:reboot_common/src/model/fortnite_version.dart';
import 'package:reboot_common/src/util/matchmaker.dart' as matchmaker;
late String? username;
@@ -46,7 +45,7 @@ void main(List<String> args) async {
if(result["update"]) {
stdout.writeln("Updating reboot dll...");
try {
await downloadRebootDll(rebootDownloadUrl, 0);
await downloadRebootDll(kRebootDownloadUrl);
}catch(error){
stderr.writeln("Cannot update reboot dll: $error");
}

View File

@@ -1,10 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:process_run/process_run.dart';
import 'package:reboot_common/common.dart';
import 'package:reboot_cli/cli.dart';
import 'package:reboot_common/common.dart';
Process? _gameProcess;
Process? _launcherProcess;
@@ -24,7 +22,7 @@ Future<void> startGame() async {
stdout.writeln("No username was specified, using $username by default. Use --username to specify one");
}
_gameProcess = await Process.start(executable.path, createRebootArgs(username!, "", host, ""))
_gameProcess = await Process.start(executable.path, createRebootArgs(username!, "", host, host, ""))
..exitCode.then((_) => _onClose())
..outLines.forEach((line) => _onGameOutput(line, dll, host, verbose));
_injectOrShowError("cobalt.dll");
@@ -54,12 +52,12 @@ void _onGameOutput(String line, String dll, bool hosting, bool verbose) {
stdout.writeln(line);
}
if (line.contains(shutdownLine)) {
if (line.contains(kShutdownLine)) {
_onClose();
return;
}
if(cannotConnectErrors.any((element) => line.contains(element))){
if(kCannotConnectErrors.any((element) => line.contains(element))){
stderr.writeln("The backend doesn't work! Token expired");
_onClose();
return;

View File

@@ -7,7 +7,7 @@ Future<bool> startServerCli(String? host, String? port, ServerType type) async {
stdout.writeln("Starting backend server...");
switch(type){
case ServerType.local:
var result = await pingAuthenticator(host ?? kDefaultAuthenticatorHost, port ?? kDefaultAuthenticatorPort);
var result = await pingAuthenticator(host ?? kDefaultAuthenticatorHost, port ?? kDefaultAuthenticatorPort.toString());
if(result == null){
throw Exception("Local backend server is not running");
}
@@ -17,7 +17,7 @@ Future<bool> startServerCli(String? host, String? port, ServerType type) async {
case ServerType.embedded:
stdout.writeln("Starting an embedded server...");
await server.startEmbeddedAuthenticator(false);
var result = await pingAuthenticator(host ?? kDefaultAuthenticatorHost, port ?? kDefaultAuthenticatorPort);
var result = await pingAuthenticator(host ?? kDefaultAuthenticatorHost, port ?? kDefaultAuthenticatorPort.toString());
if(result == null){
throw Exception("Cannot start embedded server");
}

View File

@@ -5,7 +5,7 @@ version: "1.0.0"
publish_to: 'none'
environment:
sdk: ">=2.19.0 <=3.3.3"
sdk: ">=2.19.0 <=3.3.4"
dependencies:
reboot_common:

View File

@@ -1,11 +1,7 @@
export 'package:reboot_common/src/constant/authenticator.dart';
export 'package:reboot_common/src/constant/game.dart';
export 'package:reboot_common/src/constant/matchmaker.dart';
export 'package:reboot_common/src/constant/os.dart';
export 'package:reboot_common/src/constant/supabase.dart';
export 'package:reboot_common/src/model/archive.dart';
export 'package:reboot_common/src/model/fortnite_build.dart';
export 'package:reboot_common/src/model/fortnite_version.dart';
export 'package:reboot_common/src/model/game_instance.dart';
@@ -13,12 +9,11 @@ export 'package:reboot_common/src/model/server_result.dart';
export 'package:reboot_common/src/model/server_type.dart';
export 'package:reboot_common/src/model/update_status.dart';
export 'package:reboot_common/src/model/update_timer.dart';
export 'package:reboot_common/src/util/authenticator.dart';
export 'package:reboot_common/src/util/build.dart';
export 'package:reboot_common/src/util/dll.dart';
export 'package:reboot_common/src/util/matchmaker.dart';
export 'package:reboot_common/src/util/network.dart';
export 'package:reboot_common/src/util/patcher.dart';
export 'package:reboot_common/src/util/path.dart';
export 'package:reboot_common/src/util/process.dart';
export 'package:reboot_common/src/util/reboot.dart';

View File

@@ -1,2 +1,2 @@
const String kDefaultAuthenticatorHost = "127.0.0.1";
const String kDefaultAuthenticatorPort = "3551";
const int kDefaultAuthenticatorPort = 3551;

View File

@@ -1,12 +1,13 @@
const String kDefaultPlayerName = "Player";
const String kDefaultGameServerHost = "127.0.0.1";
const String kDefaultGameServerPort = "7777";
const String shutdownLine = "FOnlineSubsystemGoogleCommon::Shutdown()";
const List<String> corruptedBuildErrors = [
const String kConsoleLine = "Region ";
const String kShutdownLine = "FOnlineSubsystemGoogleCommon::Shutdown()";
const List<String> kCorruptedBuildErrors = [
"when 0 bytes remain",
"Pak chunk signature verification failed!"
];
const List<String> cannotConnectErrors = [
const List<String> kCannotConnectErrors = [
"port 3551 failed: Connection refused",
"Unable to login to Fortnite servers",
"HTTP 400 response from ",

View File

@@ -1,2 +1,2 @@
const String kDefaultMatchmakerHost = "127.0.0.1";
const String kDefaultMatchmakerPort = "8080";
const int kDefaultMatchmakerPort = 8080;

View File

@@ -1 +0,0 @@
const int appBarWidth = 2;

View File

@@ -1,2 +1,2 @@
const String supabaseUrl = 'https://pocjparoguvaeeyjapjb.supabase.co';
const String supabaseAnonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBvY2pwYXJvZ3V2YWVleWphcGpiIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTUzMTM4NTUsImV4cCI6MjAxMDg4OTg1NX0.BffJtbQvX1NVUy-9Nj4GVzUJXPK_1GyezDE0V5MRiao';
const String supabaseUrl = 'https://drxuhdtyigthmjfhjgfl.supabase.co';
const String supabaseAnonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImRyeHVoZHR5aWd0aG1qZmhqZ2ZsIiwicm9sZSI6ImFub24iLCJpYXQiOjE2ODUzMDU4NjYsImV4cCI6MjAwMDg4MTg2Nn0.unuO67xf9CZgHi-3aXmC5p3RAktUfW7WwqDY-ccFN1M';

View File

@@ -1,18 +0,0 @@
import 'dart:io';
import 'dart:isolate';
class ArchiveDownloadProgress {
final double progress;
final int? minutesLeft;
final bool extracting;
ArchiveDownloadProgress(this.progress, this.minutesLeft, this.extracting);
}
class ArchiveDownloadOptions {
String archiveUrl;
Directory destination;
SendPort port;
ArchiveDownloadOptions(this.archiveUrl, this.destination, this.port);
}

View File

@@ -1,6 +1,60 @@
import 'dart:io';
import 'dart:isolate';
class FortniteBuild {
final String identifier;
final String version;
final String link;
final FortniteBuildSource source;
FortniteBuild({required this.version, required this.link});
FortniteBuild({required this.identifier, required this.version, required this.link, required this.source});
}
enum FortniteBuildSource {
manifest,
archive
}
class FortniteBuildDownloadProgress {
final double progress;
final int? minutesLeft;
final bool extracting;
FortniteBuildDownloadProgress(this.progress, this.minutesLeft, this.extracting);
}
class FortniteBuildDownloadOptions {
FortniteBuild build;
Directory destination;
SendPort port;
FortniteBuildDownloadOptions(this.build, this.destination, this.port);
}
class FortniteBuildManifestChunk {
List<int> chunksIds;
String file;
int fileSize;
FortniteBuildManifestChunk._internal(this.chunksIds, this.file, this.fileSize);
factory FortniteBuildManifestChunk.fromJson(json) => FortniteBuildManifestChunk._internal(
List<int>.from(json["ChunksIds"] as List),
json["File"],
json["FileSize"]
);
}
class FortniteBuildManifestFile {
String name;
List<FortniteBuildManifestChunk> chunks;
int size;
FortniteBuildManifestFile._internal(this.name, this.chunks, this.size);
factory FortniteBuildManifestFile.fromJson(json) => FortniteBuildManifestFile._internal(
json["Name"],
List<FortniteBuildManifestChunk>.from(json["Chunks"].map((chunk) => FortniteBuildManifestChunk.fromJson(chunk))),
json["Size"]
);
}

View File

@@ -8,35 +8,18 @@ class GameInstance {
final int? eacPid;
int? observerPid;
bool hosting;
bool launched;
bool tokenError;
bool linkedHosting;
GameInstance? child;
GameInstance(this.versionName, this.gamePid, this.launcherPid, this.eacPid, this.hosting, this.linkedHosting)
: tokenError = false,
assert(!linkedHosting || !hosting, "Only a game instance can have a linked hosting server");
GameInstance._fromJson(this.versionName, this.gamePid, this.launcherPid, this.eacPid, this.observerPid,
this.hosting, this.tokenError, this.linkedHosting);
static GameInstance? fromJson(Map<String, dynamic>? json) {
if(json == null) {
return null;
}
var gamePid = json["game"];
if(gamePid == null) {
return null;
}
var version = json["versionName"];
var launcherPid = json["launcher"];
var eacPid = json["eac"];
var observerPid = json["observer"];
var hosting = json["hosting"];
var tokenError = json["tokenError"];
var linkedHosting = json["linkedHosting"];
return GameInstance._fromJson(version, gamePid, launcherPid, eacPid, observerPid, hosting, tokenError, linkedHosting);
}
GameInstance({
required this.versionName,
required this.gamePid,
required this.launcherPid,
required this.eacPid,
required this.hosting,
required this.child
}): tokenError = false, launched = false;
void kill() {
Process.killPid(gamePid, ProcessSignal.sigabrt);
@@ -49,16 +32,6 @@ class GameInstance {
if(observerPid != null) {
Process.killPid(observerPid!, ProcessSignal.sigabrt);
}
child?.kill();
}
Map<String, dynamic> toJson() => {
'versionName': versionName,
'game': gamePid,
'launcher': launcherPid,
'eac': eacPid,
'observer': observerPid,
'hosting': hosting,
'tokenError': tokenError,
'linkedHosting': linkedHosting
};
}

View File

@@ -6,30 +6,27 @@ import 'package:shelf_proxy/shelf_proxy.dart';
final authenticatorDirectory = Directory("${assetsDirectory.path}\\authenticator");
final authenticatorStartExecutable = File("${authenticatorDirectory.path}\\lawinserver.exe");
final authenticatorKillExecutable = File("${authenticatorDirectory.path}\\kill.bat");
Future<int> startEmbeddedAuthenticator(bool detached) async => startBackgroundProcess(
executable: authenticatorStartExecutable,
window: detached
);
Future<HttpServer> startRemoteAuthenticatorProxy(Uri uri) async => await serve(proxyHandler(uri), kDefaultAuthenticatorHost, int.parse(kDefaultAuthenticatorPort));
Future<HttpServer> startRemoteAuthenticatorProxy(Uri uri) async {
print("CALLED: $uri");
return await serve(proxyHandler(uri), kDefaultAuthenticatorHost, kDefaultAuthenticatorPort);
}
Future<bool> isAuthenticatorPortFree() async => isPortFree(int.parse(kDefaultAuthenticatorPort));
Future<bool> isAuthenticatorPortFree() async => await pingAuthenticator(kDefaultAuthenticatorHost, kDefaultAuthenticatorPort.toString()) == null;
Future<bool> freeAuthenticatorPort() async {
await Process.run(authenticatorKillExecutable.path, []);
var standardResult = await isAuthenticatorPortFree();
await killProcessByPort(kDefaultAuthenticatorPort);
final standardResult = await isAuthenticatorPortFree();
if(standardResult) {
return true;
}
var elevatedResult = await runElevatedProcess(authenticatorKillExecutable.path, "");
if(!elevatedResult) {
return false;
}
return await isAuthenticatorPortFree();
return false;
}
Future<Uri?> pingAuthenticator(String host, String port, [bool https=false]) async {
@@ -48,7 +45,7 @@ Future<Uri?> pingAuthenticator(String host, String port, [bool https=false]) asy
var response = await request.close();
return response.statusCode == 200 || response.statusCode == 404 ? uri : null;
}catch(_){
return https || declaredScheme != null ? null : await pingAuthenticator(host, port, true);
return https || declaredScheme != null || isLocalHost(host) ? null : await pingAuthenticator(host, port, true);
}
}

View File

@@ -2,24 +2,62 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
import 'package:dio/dio.dart';
const String kStopBuildDownloadSignal = "kill";
final Dio _dio = Dio();
final String _manifestSourceUrl = "https://raw.githubusercontent.com/simplyblk/Fortnitebuilds/main/README.md";
final String _archiveSourceUrl = "https://raw.githubusercontent.com/simplyblk/Fortnitebuilds/main/README.md";
final RegExp _rarProgressRegex = RegExp("^((100)|(\\d{1,2}(.\\d*)?))%\$");
const String _manifestSourceUrl = "https://manifest.fnbuilds.services";
const int _maxDownloadErrors = 30;
Future<List<FortniteBuild>> fetchBuilds(ignored) async {
var response = await _dio.get<String>(
_manifestSourceUrl,
final results = await Future.wait([_fetchManifestBuilds(), _fetchArchiveBuilds()]);
final data = <FortniteBuild>[];
for(final result in results) {
data.addAll(result);
}
return data;
}
Future<List<FortniteBuild>> _fetchManifestBuilds() async {
try {
final response = await _dio.get<String>("$_manifestSourceUrl/versions.json");
final body = response.data;
return jsonDecode(body!).map((version) {
final nameParts = version.split("-");
if(nameParts.length < 2) {
return null;
}
final name = nameParts[1];
return FortniteBuild(
identifier: name,
version: "Fortnite ${name}",
link: "$_manifestSourceUrl/$name/$name.manifest",
source: FortniteBuildSource.manifest
);
}).whereType<FortniteBuild>().toList();
}catch(_) {
return [];
}
}
Future<List<FortniteBuild>> _fetchArchiveBuilds() async {
final response = await _dio.get<String>(
_archiveSourceUrl,
options: Options(
responseType: ResponseType.plain
)
);
if (response.statusCode != 200) {
throw Exception("Erroneous status code: ${response.statusCode}");
return [];
}
var results = <FortniteBuild>[];
@@ -40,63 +78,154 @@ Future<List<FortniteBuild>> fetchBuilds(ignored) async {
var version = parts.first.trim();
version = version.substring(0, version.indexOf("-"));
results.add(FortniteBuild(version: "Fortnite $version", link: link));
results.add(FortniteBuild(
identifier: version,
version: "Fortnite $version",
link: link,
source: FortniteBuildSource.archive
));
}
return results;
}
Future<void> downloadArchiveBuild(ArchiveDownloadOptions options) async {
var stopped = _setupLifecycle(options);
var outputDir = Directory("${options.destination.path}\\.build");
outputDir.createSync(recursive: true);
options.destination.createSync(recursive: true);
var fileName = options.archiveUrl.substring(options.archiveUrl.lastIndexOf("/") + 1);
var extension = path.extension(fileName);
var tempFile = File("${outputDir.path}\\$fileName");
if(tempFile.existsSync()) {
tempFile.deleteSync(recursive: true);
}
Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
try {
final stopped = _setupLifecycle(options);
switch(options.build.source) {
case FortniteBuildSource.archive:
final outputDir = Directory("${options.destination.path}\\.build");
await outputDir.create(recursive: true);
final fileName = options.build.link.substring(options.build.link.lastIndexOf("/") + 1);
final extension = path.extension(fileName);
final tempFile = File("${outputDir.path}\\$fileName");
if(await tempFile.exists()) {
await tempFile.delete(recursive: true);
}
var startTime = DateTime.now().millisecondsSinceEpoch;
var response = _downloadFile(options, tempFile, startTime);
await Future.any([stopped.future, response]);
if(!stopped.isCompleted) {
var awaitedResponse = await response;
if (!awaitedResponse.statusCode.toString().startsWith("20")) {
throw Exception("Erroneous status code: ${awaitedResponse.statusCode}");
final startTime = DateTime.now().millisecondsSinceEpoch;
final response = _downloadArchive(options, tempFile, startTime);
await Future.any([stopped.future, response]);
if(!stopped.isCompleted) {
var awaitedResponse = await response;
if (!awaitedResponse.statusCode.toString().startsWith("20")) {
options.port.send("Erroneous status code: ${awaitedResponse.statusCode}");
return;
}
await _extractArchive(stopped, extension, tempFile, options);
}
delete(outputDir);
break;
case FortniteBuildSource.manifest:
final response = await _dio.get<String>(options.build.link);
final manifest = FortniteBuildManifestFile.fromJson(jsonDecode(response.data!));
final totalBytes = manifest.size;
final outputDir = options.destination;
await outputDir.create(recursive: true);
final startTime = DateTime.now().millisecondsSinceEpoch;
final codec = GZipCodec();
var completedBytes = 0;
var lastPercentage = 0.0;
final writers = manifest.chunks.map((chunkedFile) async {
final outputFile = File('${outputDir.path}/${chunkedFile.file}');
if(outputFile.existsSync()) {
if(outputFile.lengthSync() != chunkedFile.fileSize) {
await outputFile.delete();
} else {
completedBytes += chunkedFile.fileSize;
final percentage = completedBytes * 100 / totalBytes;
if(percentage - lastPercentage > 0.1) {
_onProgress(
startTime,
DateTime.now().millisecondsSinceEpoch,
percentage,
false,
options
);
}
return;
}
}
await outputFile.parent.create(recursive: true);
for(final chunkId in chunkedFile.chunksIds) {
final response = await _dio.get<Uint8List>(
"$_manifestSourceUrl/${options.build.identifier}/$chunkId.chunk",
options: Options(
responseType: ResponseType.bytes,
headers: {
"Accept-Encoding": "gzip"
}
),
);
var responseBody = response.data;
if(responseBody == null) {
continue;
}
final decodedBody = codec.decode(responseBody);
await outputFile.writeAsBytes(
decodedBody,
mode: FileMode.append,
flush: true
);
completedBytes += decodedBody.length;
final percentage = completedBytes * 100 / totalBytes;
if(percentage - lastPercentage > 0.1) {
_onProgress(
startTime,
DateTime.now().millisecondsSinceEpoch,
percentage,
false,
options
);
}
}
});
await Future.any([stopped.future, Future.wait(writers)]);
options.port.send(FortniteBuildDownloadProgress(100, 0, true));
break;
}
}catch(error, stackTrace) {
options.port.send("$error\n$stackTrace");
}
}
Future<Response> _downloadArchive(FortniteBuildDownloadOptions options, File tempFile, int startTime, [int? byteStart = null, int errorsCount = 0]) async {
var received = byteStart ?? 0;
try {
return await _dio.download(
options.build.link,
tempFile.path,
onReceiveProgress: (data, length) {
received = data;
final percentage = (received / length) * 100;
_onProgress(startTime, DateTime.now().millisecondsSinceEpoch, percentage, false, options);
},
deleteOnError: false,
options: Options(
headers: byteStart == null ? null : {
"Range": "bytes=${byteStart}-"
}
)
);
}catch(error) {
if(errorsCount >= _maxDownloadErrors) {
throw error;
}
await _extract(stopped, extension, tempFile, options);
return await _downloadArchive(options, tempFile, startTime, received, errorsCount + 1);
}
delete(outputDir);
}
Future<Response> _downloadFile(ArchiveDownloadOptions options, File tempFile, int startTime, [int? byteStart = null]) {
var received = byteStart ?? 0;
return _dio.download(
options.archiveUrl,
tempFile.path,
onReceiveProgress: (data, length) {
received = data;
var now = DateTime.now();
var progress = (received / length) * 100;
var msLeft = startTime + (now.millisecondsSinceEpoch - startTime) * length / received - now.millisecondsSinceEpoch;
var minutesLeft = (msLeft / 1000 / 60).round();
options.port.send(ArchiveDownloadProgress(progress, minutesLeft, false));
},
deleteOnError: false,
options: Options(
headers: byteStart == null ? null : {
"Range": "bytes=${byteStart}-"
}
)
).catchError((error) => _downloadFile(options, tempFile, startTime, received));
}
Future<void> _extract(Completer<dynamic> stopped, String extension, File tempFile, ArchiveDownloadOptions options) async {
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
var startTime = DateTime.now().millisecondsSinceEpoch;
Process? process;
switch (extension.toLowerCase()) {
@@ -106,25 +235,20 @@ Future<void> _extract(Completer<dynamic> stopped, String extension, File tempFil
["a", "-bsp1", '-o"${options.destination.path}"', tempFile.path]
);
process.stdout.listen((bytes) {
var now = DateTime.now().millisecondsSinceEpoch;
var data = utf8.decode(bytes);
final now = DateTime.now().millisecondsSinceEpoch;
final data = utf8.decode(bytes);
if(data == "Everything is Ok") {
options.port.send(ArchiveDownloadProgress(100, 0, true));
options.port.send(FortniteBuildDownloadProgress(100, 0, true));
return;
}
var element = data.trim().split(" ")[0];
final element = data.trim().split(" ")[0];
if(!element.endsWith("%")) {
return;
}
var percentage = int.parse(element.substring(0, element.length - 1));
if(percentage == 0) {
options.port.send(ArchiveDownloadProgress(percentage.toDouble(), null, true));
return;
}
_onProgress(startTime, now, percentage, options);
final percentage = int.parse(element.substring(0, element.length - 1)).toDouble();
_onProgress(startTime, now, percentage, true, options);
});
break;
case ".rar":
@@ -133,34 +257,29 @@ Future<void> _extract(Completer<dynamic> stopped, String extension, File tempFil
["x", "-o+", tempFile.path, "*.*", options.destination.path]
);
process.stdout.listen((event) {
var now = DateTime.now().millisecondsSinceEpoch;
var data = utf8.decode(event);
final now = DateTime.now().millisecondsSinceEpoch;
final data = utf8.decode(event);
data.replaceAll("\r", "")
.replaceAll("\b", "")
.trim()
.split("\n")
.forEach((entry) {
if(entry == "All OK") {
options.port.send(ArchiveDownloadProgress(100, 0, true));
return;
}
if(entry == "All OK") {
options.port.send(FortniteBuildDownloadProgress(100, 0, true));
return;
}
var element = _rarProgressRegex.firstMatch(entry)?.group(1);
if(element == null) {
return;
}
final element = _rarProgressRegex.firstMatch(entry)?.group(1);
if(element == null) {
return;
}
var percentage = int.parse(element);
if(percentage == 0) {
options.port.send(ArchiveDownloadProgress(percentage.toDouble(), null, true));
return;
}
_onProgress(startTime, now, percentage, options);
});
final percentage = int.parse(element).toDouble();
_onProgress(startTime, now, percentage, true, options);
});
});
process.stderr.listen((event) {
var data = utf8.decode(event);
final data = utf8.decode(event);
options.port.send(data);
});
break;
@@ -171,17 +290,22 @@ Future<void> _extract(Completer<dynamic> stopped, String extension, File tempFil
await Future.any([stopped.future, process.exitCode]);
}
void _onProgress(int startTime, int now, int percentage, ArchiveDownloadOptions options) {
var msLeft = startTime + (now - startTime) * 100 / percentage - now;
var minutesLeft = (msLeft / 1000 / 60).round();
options.port.send(ArchiveDownloadProgress(percentage.toDouble(), minutesLeft, true));
void _onProgress(int startTime, int now, double percentage, bool extracting, FortniteBuildDownloadOptions options) {
if(percentage == 0) {
options.port.send(FortniteBuildDownloadProgress(percentage, null, extracting));
return;
}
final msLeft = startTime + (now - startTime) * 100 / percentage - now;
final minutesLeft = (msLeft / 1000 / 60).round();
options.port.send(FortniteBuildDownloadProgress(percentage, minutesLeft, extracting));
}
Completer<dynamic> _setupLifecycle(ArchiveDownloadOptions options) {
Completer<dynamic> _setupLifecycle(FortniteBuildDownloadOptions options) {
var stopped = Completer();
var lifecyclePort = ReceivePort();
lifecyclePort.listen((message) {
if(message == "kill") {
if(message == kStopBuildDownloadSignal && !stopped.isCompleted) {
stopped.complete();
}
});

View File

@@ -0,0 +1,64 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
bool _watcher = false;
final File rebootDllFile = File("${assetsDirectory.path}\\dlls\\reboot.dll");
const String kRebootDownloadUrl =
"https://nightly.link/Milxnor/Project-Reboot-3.0/workflows/msbuild/master/Release.zip";
Future<bool> hasRebootDllUpdate(int? lastUpdateMs, {int hours = 24, bool force = false}) async {
final lastUpdate = await _getLastUpdate(lastUpdateMs);
final exists = await rebootDllFile.exists();
final now = DateTime.now();
return force || !exists || (hours > 0 && lastUpdate != null && now.difference(lastUpdate).inHours > hours);
}
Future<void> downloadCriticalDll(String name, String outputPath) async {
final response = await http.get(Uri.parse("https://github.com/Auties00/reboot_launcher/tree/master/gui/assets/dlls/$name"));
final output = File(outputPath);
await output.parent.create(recursive: true);
await output.writeAsBytes(response.bodyBytes);
}
Future<int> downloadRebootDll(String url) async {
Directory? outputDir;
final now = DateTime.now();
try {
final response = await http.get(Uri.parse(url));
outputDir = await installationDirectory.createTemp("reboot_out");
final tempZip = File("${outputDir.path}\\reboot.zip");
await tempZip.writeAsBytes(response.bodyBytes);
await extractFileToDisk(tempZip.path, outputDir.path);
final rebootDll = File(outputDir.listSync().firstWhere((element) => path.extension(element.path) == ".dll").path);
await rebootDllFile.writeAsBytes(await rebootDll.readAsBytes());
return now.millisecondsSinceEpoch;
} finally{
if(outputDir != null) {
delete(outputDir);
}
}
}
Future<DateTime?> _getLastUpdate(int? lastUpdateMs) async {
return lastUpdateMs != null
? DateTime.fromMillisecondsSinceEpoch(lastUpdateMs)
: null;
}
Stream<String> watchDlls() async* {
if(_watcher) {
return;
}
_watcher = true;
await for(final event in rebootDllFile.parent.watch(events: FileSystemEvent.delete | FileSystemEvent.move)) {
print(event);
if (event.path.endsWith(".dll")) {
yield event.path;
}
}
}

View File

@@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:io';
import 'package:ini/ini.dart';
import 'package:reboot_common/common.dart';
import 'package:sync/semaphore.dart';
@@ -75,21 +74,16 @@ Future<void> writeMatchmakingIp(String text) async {
await matchmakerConfigFile.writeAsString(config.toString(), flush: true);
}
Future<bool> isMatchmakerPortFree() async => isPortFree(int.parse(kDefaultMatchmakerPort));
Future<bool> isMatchmakerPortFree() async => await pingMatchmaker(kDefaultMatchmakerHost, kDefaultMatchmakerPort.toString()) == null;
Future<bool> freeMatchmakerPort() async {
await Process.run(matchmakerKillExecutable.path, []);
var standardResult = await isMatchmakerPortFree();
await killProcessByPort(kDefaultMatchmakerPort);
final standardResult = await isMatchmakerPortFree();
if(standardResult) {
return true;
}
var elevatedResult = await runElevatedProcess(matchmakerKillExecutable.path, "");
if(!elevatedResult) {
return false;
}
return await isMatchmakerPortFree();
return false;
}
Future<Uri?> pingMatchmaker(String host, String port, [bool wss=false]) async {
@@ -124,7 +118,7 @@ Future<Uri?> pingMatchmaker(String host, String port, [bool wss=false]) async {
await socket.close();
return result ? uri : null;
}catch(_){
return wss || declaredScheme != null ? null : await pingMatchmaker(host, port, true);
return wss || declaredScheme != null || isLocalHost(host) ? null : await pingMatchmaker(host, port, true);
}
}

View File

@@ -1,22 +1,95 @@
import 'dart:io';
import 'dart:ffi';
import 'package:reboot_common/common.dart';
import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';
const _AF_INET = 2;
const _TCP_TABLE_OWNER_PID_LISTENER = 3;
final _getExtendedTcpTable = DynamicLibrary.open('iphlpapi.dll').lookupFunction<
Int32 Function(Pointer, Pointer<Uint32>, Int32, Int32, Int32, Int32),
int Function(Pointer, Pointer<Uint32>, int, int, int, int)>('GetExtendedTcpTable');
class _MIB_TCPROW_OWNER_PID extends Struct {
@Uint32()
external int dwState;
@Uint32()
external int dwLocalAddr;
@Uint32()
external int dwLocalPort;
@Uint32()
external int dwRemoteAddr;
@Uint32()
external int dwRemotePort;
@Uint32()
external int dwOwningPid;
}
class _MIB_TCPTABLE_OWNER_PID extends Struct {
@Uint32()
external int dwNumEntries;
@Array(1)
external Array<_MIB_TCPROW_OWNER_PID> table;
}
bool isLocalHost(String host) => host.trim() == "127.0.0.1"
|| host.trim().toLowerCase() == "localhost"
|| host.trim() == "0.0.0.0";
Future<bool> isPortFree(int port) async {
try {
final server = await ServerSocket.bind(InternetAddress.anyIPv4, port);
await server.close();
return true;
} catch (e) {
return false;
bool killProcessByPort(int port) {
var pTcpTable = calloc<_MIB_TCPTABLE_OWNER_PID>();
final dwSize = calloc<DWORD>();
dwSize.value = 0;
int result = _getExtendedTcpTable(
nullptr,
dwSize,
FALSE,
_AF_INET,
_TCP_TABLE_OWNER_PID_LISTENER,
0
);
if (result == ERROR_INSUFFICIENT_BUFFER) {
pTcpTable = calloc<_MIB_TCPTABLE_OWNER_PID>(dwSize.value);
result = _getExtendedTcpTable(
pTcpTable,
dwSize,
FALSE,
_AF_INET,
_TCP_TABLE_OWNER_PID_LISTENER,
0
);
}
if (result == NO_ERROR) {
final table = pTcpTable.ref;
for (int i = 0; i < table.dwNumEntries; i++) {
final row = table.table[i];
final localPort = _htons(row.dwLocalPort);
if (localPort == port) {
final pid = row.dwOwningPid;
calloc.free(pTcpTable);
calloc.free(dwSize);
final hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProcess != NULL) {
final result = TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
return result != 0;
}
return false;
}
}
}
calloc.free(pTcpTable);
calloc.free(dwSize);
return false;
}
Future<void> resetWinNat() async {
var binary = File("${assetsDirectory.path}\\misc\\winnat.bat");
await runElevatedProcess(binary.path, "");
}
int _htons(int port) => ((port & 0xFF) << 8) | ((port >> 8) & 0xFF);

View File

@@ -1,8 +1,8 @@
import 'dart:io';
import 'dart:isolate';
import 'package:reboot_common/common.dart';
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
Directory get installationDirectory =>
File(Platform.resolvedExecutable).parent;

View File

@@ -4,10 +4,13 @@ import 'dart:async';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';
import '../constant/game.dart';
final _ntdll = DynamicLibrary.open('ntdll.dll');
final _kernel32 = DynamicLibrary.open('kernel32.dll');
final _CreateRemoteThread = _kernel32.lookupFunction<
@@ -84,23 +87,23 @@ Future<void> injectDll(int pid, String dll) async {
}
}
Future<bool> runElevatedProcess(String executable, String args) async {
var shellInput = calloc<SHELLEXECUTEINFO>();
bool runElevatedProcess(String executable, String args) {
final shellInput = calloc<SHELLEXECUTEINFO>();
shellInput.ref.lpFile = executable.toNativeUtf16();
shellInput.ref.lpParameters = args.toNativeUtf16();
shellInput.ref.nShow = SW_HIDE;
shellInput.ref.fMask = ES_AWAYMODE_REQUIRED;
shellInput.ref.lpVerb = "runas".toNativeUtf16();
shellInput.ref.cbSize = sizeOf<SHELLEXECUTEINFO>();
var shellResult = ShellExecuteEx(shellInput);
return shellResult == 1;
final result = ShellExecuteEx(shellInput) == 1;
free(shellInput);
return result;
}
void _startBackgroundProcess(_BackgroundProcessParameters params) {
var args = params.args;
var concatenatedArgs = args == null ? "" : " ${args.map((entry) => '"$entry"').join(" ")}";
var executablePath = TEXT("${params.executable.path}$concatenatedArgs");
var executablePath = TEXT('cmd.exe /k "${params.executable.path}"$concatenatedArgs');
var startupInfo = calloc<STARTUPINFO>();
var processInfo = calloc<PROCESS_INFORMATION>();
var windowFlag = params.window ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW;
@@ -204,3 +207,56 @@ Future<bool> watchProcess(int pid) async {
isolate.kill(priority: Isolate.immediate);
return result;
}
List<String> createRebootArgs(String username, String password, bool host, bool headless, String additionalArgs) {
if(password.isEmpty) {
username = '${_parseUsername(username, host)}@projectreboot.dev';
}
password = password.isNotEmpty ? password : "Rebooted";
var args = [
"-epicapp=Fortnite",
"-epicenv=Prod",
"-epiclocale=en-us",
"-epicportal",
"-skippatchcheck",
"-nobe",
"-fromfl=eac",
"-fltoken=3db3ba5dcbd2e16703f3978d",
"-caldera=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50X2lkIjoiYmU5ZGE1YzJmYmVhNDQwN2IyZjQwZWJhYWQ4NTlhZDQiLCJnZW5lcmF0ZWQiOjE2Mzg3MTcyNzgsImNhbGRlcmFHdWlkIjoiMzgxMGI4NjMtMmE2NS00NDU3LTliNTgtNGRhYjNiNDgyYTg2IiwiYWNQcm92aWRlciI6IkVhc3lBbnRpQ2hlYXQiLCJub3RlcyI6IiIsImZhbGxiYWNrIjpmYWxzZX0.VAWQB67RTxhiWOxx7DBjnzDnXyyEnX7OljJm-j2d88G_WgwQ9wrE6lwMEHZHjBd1ISJdUO1UVUqkfLdU5nofBQ",
"-AUTH_LOGIN=$username",
"-AUTH_PASSWORD=${password.isNotEmpty ? password : "Rebooted"}",
"-AUTH_TYPE=epic"
];
if(host && headless){
args.addAll([
"-nullrhi",
"-nosplash",
"-nosound",
]);
}
if(additionalArgs.isNotEmpty){
args.addAll(additionalArgs.split(" "));
}
return args;
}
String _parseUsername(String username, bool host) {
if(host) {
return "Player${Random().nextInt(1000)}";
}
if (username.isEmpty) {
return kDefaultPlayerName;
}
username = username.replaceAll(RegExp("[^A-Za-z0-9]"), "").trim();
if(username.isEmpty){
return kDefaultPlayerName;
}
return username;
}

View File

@@ -1,100 +0,0 @@
import 'dart:io';
import 'dart:math';
import 'package:archive/archive_io.dart';
import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'package:reboot_common/common.dart';
const String rebootDownloadUrl =
"https://nightly.link/Milxnor/Project-Reboot-3.0/workflows/msbuild/main/Release.zip";
final File rebootDllFile = File("${assetsDirectory.path}\\dlls\\reboot.dll");
List<String> createRebootArgs(String username, String password, bool host, String additionalArgs) {
if(password.isEmpty) {
username = '${_parseUsername(username, host)}@projectreboot.dev';
}
password = password.isNotEmpty ? password : "Rebooted";
var args = [
"-epicapp=Fortnite",
"-epicenv=Prod",
"-epiclocale=en-us",
"-epicportal",
"-skippatchcheck",
"-nobe",
"-fromfl=eac",
"-fltoken=3db3ba5dcbd2e16703f3978d",
"-caldera=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50X2lkIjoiYmU5ZGE1YzJmYmVhNDQwN2IyZjQwZWJhYWQ4NTlhZDQiLCJnZW5lcmF0ZWQiOjE2Mzg3MTcyNzgsImNhbGRlcmFHdWlkIjoiMzgxMGI4NjMtMmE2NS00NDU3LTliNTgtNGRhYjNiNDgyYTg2IiwiYWNQcm92aWRlciI6IkVhc3lBbnRpQ2hlYXQiLCJub3RlcyI6IiIsImZhbGxiYWNrIjpmYWxzZX0.VAWQB67RTxhiWOxx7DBjnzDnXyyEnX7OljJm-j2d88G_WgwQ9wrE6lwMEHZHjBd1ISJdUO1UVUqkfLdU5nofBQ",
"-AUTH_LOGIN=$username",
"-AUTH_PASSWORD=${password.isNotEmpty ? password : "Rebooted"}",
"-AUTH_TYPE=epic"
];
if(host){
args.addAll([
"-nullrhi",
"-nosplash",
"-nosound",
]);
}
if(additionalArgs.isNotEmpty){
args.addAll(additionalArgs.split(" "));
}
return args;
}
String _parseUsername(String username, bool host) {
if(host) {
return "Player${Random().nextInt(1000)}";
}
if (username.isEmpty) {
return kDefaultPlayerName;
}
username = username.replaceAll(RegExp("[^A-Za-z0-9]"), "").trim();
if(username.isEmpty){
return kDefaultPlayerName;
}
return username;
}
Future<int> downloadRebootDll(String url, int? lastUpdateMs, {int hours = 24, bool force = false}) async {
Directory? outputDir;
var now = DateTime.now();
try {
var lastUpdate = await _getLastUpdate(lastUpdateMs);
var exists = await rebootDllFile.exists();
if (!force && lastUpdate != null && now.difference(lastUpdate).inHours <= hours && exists) {
return lastUpdateMs!;
}
var response = await http.get(Uri.parse(rebootDownloadUrl));
outputDir = await installationDirectory.createTemp("reboot_out");
var tempZip = File("${outputDir.path}\\reboot.zip");
await tempZip.writeAsBytes(response.bodyBytes);
await extractFileToDisk(tempZip.path, outputDir.path);
var rebootDll = File(outputDir.listSync().firstWhere((element) => path.extension(element.path) == ".dll").path);
if (!exists || sha1.convert(await rebootDllFile.readAsBytes()) != sha1.convert(await rebootDll.readAsBytes())) {
await rebootDllFile.writeAsBytes(await rebootDll.readAsBytes());
}
return now.millisecondsSinceEpoch;
} finally{
if(outputDir != null) {
delete(outputDir);
}
}
}
Future<DateTime?> _getLastUpdate(int? lastUpdateMs) async {
return lastUpdateMs != null
? DateTime.fromMillisecondsSinceEpoch(lastUpdateMs)
: null;
}

View File

@@ -4,7 +4,7 @@ version: "1.0.0"
publish_to: 'none'
environment:
sdk: ">=2.19.0 <=3.3.3"
sdk: ">=2.19.0 <=3.3.4"
dependencies:
dio: ^5.3.2

View File

@@ -1,4 +1,5 @@
import 'dart:io';
import 'package:reboot_common/common.dart';
import 'package:supabase/supabase.dart';
@@ -19,7 +20,7 @@ void main(List<String> args) async {
Process.killPid(launcherPid, ProcessSignal.sigabrt);
Process.killPid(eacPid, ProcessSignal.sigabrt);
if(hosting) {
await supabase.from('hosts')
await supabase.from("hosting")
.delete()
.match({'id': uuid});
}

View File

@@ -4,7 +4,7 @@ version: "1.0.0"
publish_to: 'none'
environment:
sdk: ">=2.19.0 <=3.3.3"
sdk: ">=2.19.0 <=3.3.4"
dependencies:
supabase: ^1.9.1

Submodule dependencies/authenticator deleted from 2ea81cbde5

Submodule dependencies/matchmaker deleted from 0047d0db97

View File

@@ -1,2 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto

View File

@@ -1,47 +0,0 @@
name: MSBuild
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
# Path to the solution file relative to the root of the project.
SOLUTION_FILE_PATH: .
# Configuration type to build.
# You can convert this to a build matrix if you need coverage of multiple configuration types.
# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
BUILD_CONFIGURATION: Release
permissions:
contents: read
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.2
- name: Restore NuGet packages
working-directory: ${{env.GITHUB_WORKSPACE}}
run: nuget restore ${{env.SOLUTION_FILE_PATH}}
- name: Build
working-directory: ${{env.GITHUB_WORKSPACE}}
# Add additional options to the MSBuild command line here (like platform or verbosity level).
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
- name: Upload Release Artifact
uses: actions/upload-artifact@v3
with:
name: Release
path: ${{env.SOLUTION_FILE_PATH}}/x64/Release
if-no-files-found: warn
retention-days: 60

View File

@@ -1,387 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
.vs/Project Reboot 3.0/v17/Browse.VC.db
.vs/Project Reboot 3.0/v17/.suo
.vs/Project Reboot 3.0/v17/fileList.bin
.vs/Project Reboot 3.0/v17/ipch/AutoPCH/389a1fa1f6dcd16f/DLLMAIN.ipch
.vs/Project Reboot 3.0/v17/ipch/AutoPCH/6b05e7771d6ded15/UTIL.ipch
Project Reboot 3.0/x64/Release/Project Reboot 3.0.tlog/CL.read.1.tlog
Project Reboot 3.0/x64/Release/Project Reboot 3.0.tlog/link.read.1.tlog
Project Reboot 3.0/x64/Release/Project Reboot 3.0.tlog/CL.write.1.tlog
Project Reboot 3.0e/x64/Release/vc143.pdb
x64/Release/Project Reboot 3.0.pdb
Project Reboot 3.0/x64/Release/Project Reboot 3.0.log
Project Reboot 3.0/x64/Release/Project Reboot 3.0.ipdb
Project Reboot 3.0/x64/Release/Project Reboot 3.0.iobj
.vs/Project Reboot 3.0/v17/Browse.VC.db
.vs/Project Reboot 3.0/v17/.suo
.vs/Project Reboot 3.0/v17/.suo
*.db
*.bin
*.ipch
*.ipdb
*.iobj
*.tlog
*.ifc
*.pdb

View File

@@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2023, Milxnor
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32630.192
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Project Reboot 3.0", "Project Reboot 3.0\Project Reboot 3.0.vcxproj", "{69618184-B9DB-4982-B4FE-F83E9BDD0555}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Debug|x64.ActiveCfg = Debug|x64
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Debug|x64.Build.0 = Debug|x64
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Debug|x86.ActiveCfg = Debug|Win32
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Debug|x86.Build.0 = Debug|Win32
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Release|x64.ActiveCfg = Release|x64
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Release|x64.Build.0 = Release|x64
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Release|x86.ActiveCfg = Release|Win32
{69618184-B9DB-4982-B4FE-F83E9BDD0555}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {ABF83670-C6F5-441C-9B62-254EF634207B}
EndGlobalSection
EndGlobal

View File

@@ -1,103 +0,0 @@
#pragma once
#include "Object.h"
#include "GameplayAbilitySpec.h"
#include "AttributeSet.h"
struct PadHex10 { char Pad[0x10]; };
struct PadHex18 { char Pad[0x18]; };
struct PadHexA8 { char Pad[0xA8]; };
struct PadHexB0 { char Pad[0xB0]; };
// using FPredictionKey = PadHex18;
// using FGameplayEventData = PadHexA8;
// using FPredictionKey = PadHex10;
using FGameplayEventData = PadHexB0;
// using FGameplayEventData = __int64;
struct FPredictionKey // todo move
{
// __int64 real;
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/GameplayAbilities.PredictionKey");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
};
struct FGameplayEffectContextHandle
{
unsigned char UnknownData00[0x18]; // 0x0000(0x0018) MISSED OFFSET
};
struct FActiveGameplayEffectHandle
{
int Handle; // 0x0000(0x0004) (ZeroConstructor, IsPlainOldData)
bool bPassedFiltersAndWasExecuted; // 0x0004(0x0001) (ZeroConstructor, IsPlainOldData)
unsigned char UnknownData00[0x3]; // 0x0005(0x0003) MISSED OFFSET
};
struct FGameplayAbilitySpecContainer : public FFastArraySerializer
{
TArray<FGameplayAbilitySpec>& GetItems()
{
static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items");
return *(TArray<FGameplayAbilitySpec>*)(__int64(this) + ItemsOffset);
}
};
class UAbilitySystemComponent : public UObject
{
public:
static inline FGameplayAbilitySpecHandle* (*GiveAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle*, __int64 inSpec);
static inline bool (*InternalTryActivateAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, PadHex10 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData);
static inline bool (*InternalTryActivateAbilityOriginal2)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, PadHex18 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData);
void ClientActivateAbilityFailed(FGameplayAbilitySpecHandle AbilityToActivate, int16_t PredictionKey)
{
struct { FGameplayAbilitySpecHandle AbilityToActivate; int16_t PredictionKey; } UAbilitySystemComponent_ClientActivateAbilityFailed_Params{ AbilityToActivate, PredictionKey };
static auto fn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ClientActivateAbilityFailed");
this->ProcessEvent(fn, &UAbilitySystemComponent_ClientActivateAbilityFailed_Params);
}
TArray<UAttributeSet*>& GetSpawnedAttributes()
{
static auto SpawnedAttributesOffset = GetOffset("SpawnedAttributes");
return Get<TArray<UAttributeSet*>>(SpawnedAttributesOffset);
}
FGameplayAbilitySpecContainer* GetActivatableAbilities()
{
static auto ActivatableAbilitiesOffset = this->GetOffset("ActivatableAbilities");
return GetPtr<FGameplayAbilitySpecContainer>(ActivatableAbilitiesOffset);
}
UAttributeSet* AddDefaultSubobjectSet(UAttributeSet* Subobject)
{
GetSpawnedAttributes().Add(Subobject);
return Subobject;
}
void ServerEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo, FPredictionKey* PredictionKey);
void ClientEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo);
void ClientCancelAbility(FGameplayAbilitySpecHandle AbilityToCancel, FGameplayAbilityActivationInfo* ActivationInfo);
bool HasAbility(UObject* DefaultAbility);
FActiveGameplayEffectHandle ApplyGameplayEffectToSelf(UClass* GameplayEffectClass, float Level, const FGameplayEffectContextHandle& EffectContext = FGameplayEffectContextHandle());
// FGameplayEffectContextHandle MakeEffectContext();
void RemoveActiveGameplayEffectBySourceEffect(UClass* GEClass, int StacksToRemove, UAbilitySystemComponent* Instigator);
void ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey* AbilityOriginalPredictionKey);
FGameplayAbilitySpecHandle GiveAbilityEasy(UClass* AbilityClass, UObject* SourceObject = nullptr, bool bDoNotRegive = true);
FGameplayAbilitySpec* FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle);
void RemoveActiveGameplayEffectBySourceEffect(UClass* GameplayEffect, UAbilitySystemComponent* InstigatorAbilitySystemComponent, int StacksToRemove);
void ClearAbility(const FGameplayAbilitySpecHandle& Handle);
static void InternalServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, const FPredictionKey* PredictionKey, const FGameplayEventData* TriggerEventData);
};
void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<void(FGameplayAbilitySpec*)> func);

View File

@@ -1,270 +0,0 @@
#include "AbilitySystemComponent.h"
#include "NetSerialization.h"
#include "Actor.h"
#include "FortPawn.h"
#include "FortPlayerController.h"
#include "FortPlayerStateAthena.h"
void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<void(FGameplayAbilitySpec*)> func)
{
static auto ActivatableAbilitiesOffset = AbilitySystemComponent->GetOffset("ActivatableAbilities");
auto ActivatableAbilities = AbilitySystemComponent->GetPtr<FFastArraySerializer>(ActivatableAbilitiesOffset);
static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items");
auto Items = (TArray<FGameplayAbilitySpec>*)(__int64(ActivatableAbilities) + ItemsOffset);
static auto SpecSize = FGameplayAbilitySpec::GetStructSize();
if (ActivatableAbilities && Items)
{
for (int i = 0; i < Items->Num(); ++i)
{
auto CurrentSpec = Items->AtPtr(i, SpecSize); // (FGameplayAbilitySpec*)(__int64(Items->Data) + (static_cast<long long>(SpecSize) * i));
func(CurrentSpec);
}
}
}
FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectToSelf(UClass* GameplayEffectClass, float Level, const FGameplayEffectContextHandle& EffectContext)
{
static auto BP_ApplyGameplayEffectToSelfFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.BP_ApplyGameplayEffectToSelf");
struct
{
UClass* GameplayEffectClass; // (Parm, ZeroConstructor, IsPlainOldData)
float Level; // (Parm, ZeroConstructor, IsPlainOldData)
FGameplayEffectContextHandle EffectContext; // (Parm)
FActiveGameplayEffectHandle ReturnValue; // (Parm, OutParm, ReturnParm)
}UAbilitySystemComponent_BP_ApplyGameplayEffectToSelf_Params{GameplayEffectClass, Level, EffectContext};
this->ProcessEvent(BP_ApplyGameplayEffectToSelfFn, &UAbilitySystemComponent_BP_ApplyGameplayEffectToSelf_Params);
return UAbilitySystemComponent_BP_ApplyGameplayEffectToSelf_Params.ReturnValue;
}
/* FGameplayEffectContextHandle UAbilitySystemComponent::MakeEffectContext()
{
static auto MakeEffectContextFn = FindObject<UFunction>("/Script/GameplayAbilities.AbilitySystemComponent.MakeEffectContext");
FGameplayEffectContextHandle ContextHandle;
this->ProcessEvent(MakeEffectContextFn, &ContextHandle);
return ContextHandle;
} */
void UAbilitySystemComponent::ServerEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo, FPredictionKey* PredictionKey)
{
static auto ServerEndAbilityFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility");
auto Params = Alloc<void>(ServerEndAbilityFn->GetPropertiesSize());
if (!Params)
return;
static auto AbilityToEndOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility", "AbilityToEnd");
static auto ActivationInfoOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility", "ActivationInfo");
static auto PredictionKeyOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility", "PredictionKey");
*(FGameplayAbilitySpecHandle*)(__int64(Params) + AbilityToEndOffset) = AbilityToEnd;
CopyStruct((FGameplayAbilityActivationInfo*)(__int64(Params) + ActivationInfoOffset), ActivationInfo, FGameplayAbilityActivationInfo::GetStructSize());
CopyStruct((FPredictionKey*)(__int64(Params) + PredictionKeyOffset), PredictionKey, FPredictionKey::GetStructSize());
this->ProcessEvent(ServerEndAbilityFn, Params);
VirtualFree(Params, 0, MEM_RELEASE);
}
void UAbilitySystemComponent::ClientEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo)
{
static auto ClientEndAbilityFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ClientEndAbility");
auto Params = Alloc(ClientEndAbilityFn->GetPropertiesSize());
static auto AbilityToEndOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientEndAbility", "AbilityToEnd");
static auto ActivationInfoOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientEndAbility", "ActivationInfo");
*(FGameplayAbilitySpecHandle*)(__int64(Params) + AbilityToEndOffset) = AbilityToEnd;
CopyStruct((FGameplayAbilityActivationInfo*)(__int64(Params) + ActivationInfoOffset), ActivationInfo, FGameplayAbilityActivationInfo::GetStructSize());
this->ProcessEvent(ClientEndAbilityFn, Params);
VirtualFree(Params, 0, MEM_RELEASE);
}
void UAbilitySystemComponent::ClientCancelAbility(FGameplayAbilitySpecHandle AbilityToCancel, FGameplayAbilityActivationInfo* ActivationInfo)
{
static auto ClientCancelAbilityFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ClientCancelAbility");
auto Params = Alloc(ClientCancelAbilityFn->GetPropertiesSize());
static auto AbilityToCancelOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientCancelAbility", "AbilityToCancel");
static auto ActivationInfoOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientCancelAbility", "ActivationInfo");
*(FGameplayAbilitySpecHandle*)(__int64(Params) + AbilityToCancelOffset) = AbilityToCancel;
CopyStruct((FGameplayAbilityActivationInfo*)(__int64(Params) + ActivationInfoOffset), ActivationInfo, FGameplayAbilityActivationInfo::GetStructSize());
this->ProcessEvent(ClientCancelAbilityFn, Params);
VirtualFree(Params, 0, MEM_RELEASE);
}
bool UAbilitySystemComponent::HasAbility(UObject* DefaultAbility)
{
auto ActivatableAbilities = GetActivatableAbilities();
auto& Items = ActivatableAbilities->GetItems();
for (int i = 0; i < Items.Num(); ++i)
{
auto Spec = Items.AtPtr(i, FGameplayAbilitySpec::GetStructSize());
if (Spec->GetAbility() == DefaultAbility)
return true;
}
return false;
}
void UAbilitySystemComponent::RemoveActiveGameplayEffectBySourceEffect(UClass* GEClass, int StacksToRemove, UAbilitySystemComponent* Instigator)
{
static auto RemoveActiveGameplayEffectBySourceEffectFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.RemoveActiveGameplayEffectBySourceEffect");
struct { UClass* GameplayEffect; UObject* InstigatorAbilitySystemComponent; int StacksToRemove; } UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params{ GEClass, Instigator, StacksToRemove };
this->ProcessEvent(RemoveActiveGameplayEffectBySourceEffectFn, &UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params);
}
void UAbilitySystemComponent::ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey* AbilityOriginalPredictionKey)
{
// static auto AbilityTargetDataMapOffset = ActivatableAbilitiesOffset + FGameplayAbilitySpecContainerSize ?
return;
}
void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, const FPredictionKey* PredictionKey, const FGameplayEventData* TriggerEventData) // https://github.com/EpicGames/UnrealEngine/blob/4.23/Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Private/AbilitySystemComponent_Abilities.cpp#L1445
{
using UGameplayAbility = UObject;
auto Spec = AbilitySystemComponent->FindAbilitySpecFromHandle(Handle);
static auto PredictionKeyStruct = FindObject<UStruct>(L"/Script/GameplayAbilities.PredictionKey");
static auto PredictionKeySize = PredictionKeyStruct->GetPropertiesSize();
static auto CurrentOffset = FindOffsetStruct("/Script/GameplayAbilities.PredictionKey", "Current");
if (!Spec)
{
LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Rejecting ClientActivation of ability with invalid SpecHandle!");
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
return;
}
AbilitySystemComponent->ConsumeAllReplicatedData(Handle, (FPredictionKey*)PredictionKey);
/* const */ UGameplayAbility * AbilityToActivate = Spec->GetAbility();
if (!AbilityToActivate)
{
LOG_ERROR(LogAbilities, "InternalServerTryActiveAbility. Rejecting ClientActivation of unconfigured spec ability!");
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
return;
}
static auto InputPressedOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "InputPressed");
UGameplayAbility* InstancedAbility = nullptr;
SetBitfield((PlaceholderBitfield*)(__int64(Spec) + InputPressedOffset), 1, true); // InputPressed = true
bool res = false;
if (PredictionKeySize == 0x10)
res = UAbilitySystemComponent::InternalTryActivateAbilityOriginal(AbilitySystemComponent, Handle, *(PadHex10*)PredictionKey, &InstancedAbility, nullptr, TriggerEventData);
else if (PredictionKeySize == 0x18)
res = UAbilitySystemComponent::InternalTryActivateAbilityOriginal2(AbilitySystemComponent, Handle, *(PadHex18*)PredictionKey, &InstancedAbility, nullptr, TriggerEventData);
else
LOG_ERROR(LogAbilities, "Prediction key size does not match with any of them!");
if (!res)
{
LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Rejecting ClientActivation of {}. InternalTryActivateAbility failed: ", AbilityToActivate->GetName());
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
SetBitfield((PlaceholderBitfield*)(__int64(Spec) + InputPressedOffset), 1, false); // InputPressed = false
AbilitySystemComponent->GetActivatableAbilities()->MarkItemDirty(Spec);
}
else
{
// LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Activated {}", AbilityToActivate->GetName());
}
}
FGameplayAbilitySpecHandle UAbilitySystemComponent::GiveAbilityEasy(UClass* AbilityClass, UObject* SourceObject, bool bDoNotRegive)
{
if (!AbilityClass)
{
LOG_WARN(LogAbilities, "Invalid AbilityClass passed into GiveAbilityEasy!");
return FGameplayAbilitySpecHandle();
}
// LOG_INFO(LogDev, "Making spec!");
auto DefaultAbility = AbilityClass->CreateDefaultObject();
if (!DefaultAbility)
return FGameplayAbilitySpecHandle();
if (bDoNotRegive && HasAbility(DefaultAbility))
return FGameplayAbilitySpecHandle();
auto NewSpec = MakeNewSpec((UClass*)DefaultAbility, SourceObject, true);
// LOG_INFO(LogDev, "Made spec!");
FGameplayAbilitySpecHandle Handle;
GiveAbilityOriginal(this, &Handle, __int64(NewSpec));
return Handle;
}
FGameplayAbilitySpec* UAbilitySystemComponent::FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle)
{
FGameplayAbilitySpec* SpecToReturn = nullptr;
auto compareHandles = [&Handle, &SpecToReturn](FGameplayAbilitySpec* Spec) {
auto& CurrentHandle = Spec->GetHandle();
if (CurrentHandle.Handle == Handle.Handle)
{
SpecToReturn = Spec;
return;
}
};
LoopSpecs(this, compareHandles);
return SpecToReturn;
}
void UAbilitySystemComponent::RemoveActiveGameplayEffectBySourceEffect(UClass* GameplayEffect, UAbilitySystemComponent* InstigatorAbilitySystemComponent, int StacksToRemove)
{
static auto RemoveActiveGameplayEffectBySourceEffectFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.RemoveActiveGameplayEffectBySourceEffect");
struct
{
UClass* GameplayEffect; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UAbilitySystemComponent* InstigatorAbilitySystemComponent; // (Parm, ZeroConstructor, InstancedReference, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int StacksToRemove; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params{GameplayEffect, InstigatorAbilitySystemComponent, StacksToRemove};
this->ProcessEvent(RemoveActiveGameplayEffectBySourceEffectFn, &UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params);
}
void UAbilitySystemComponent::ClearAbility(const FGameplayAbilitySpecHandle& Handle)
{
if (!Addresses::ClearAbility)
{
LOG_INFO(LogDev, "Invalid clear ability!");
return;
}
static void (*ClearAbilityOriginal)(UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAbilitySpecHandle& Handle) = decltype(ClearAbilityOriginal)(Addresses::ClearAbility);
ClearAbilityOriginal(this, Handle);
}

View File

@@ -1,314 +0,0 @@
#include "Actor.h"
#include "Transform.h"
#include "reboot.h"
#include "GameplayStatics.h"
bool AActor::HasAuthority()
{
static auto RoleOffset = GetOffset("Role");
return Get<uint8_t>(RoleOffset) == 3;
}
bool AActor::IsTearOff()
{
static auto bTearOffOffset = GetOffset("bTearOff");
static auto bTearOffFieldMask = GetFieldMask(GetProperty("bTearOff"));
return ReadBitfieldValue(bTearOffOffset, bTearOffFieldMask);
}
/* FORCEINLINE */ ENetDormancy& AActor::GetNetDormancy()
{
static auto NetDormancyOffset = GetOffset("NetDormancy");
return Get<ENetDormancy>(NetDormancyOffset);
}
int32& AActor::GetNetTag()
{
static auto NetTagOffset = GetOffset("NetTag");
return Get<int32>(NetTagOffset);
}
FTransform AActor::GetTransform()
{
FTransform Ret;
static auto fn = FindObject<UFunction>(L"/Script/Engine.Actor.GetTransform");
this->ProcessEvent(fn, &Ret);
return Ret;
}
/*
UWorld* AActor::GetWorld()
{
return GetWorld(); // for real
}
*/
void AActor::SetNetDormancy(ENetDormancy Dormancy)
{
static auto SetNetDormancyFn = FindObject<UFunction>(L"/Script/Engine.Actor.SetNetDormancy");
this->ProcessEvent(SetNetDormancyFn, &Dormancy);
}
AActor* AActor::GetOwner()
{
static auto GetOwnerFunction = FindObject<UFunction>(L"/Script/Engine.Actor.GetOwner");
AActor* Owner = nullptr;
this->ProcessEvent(GetOwnerFunction, &Owner);
return Owner;
}
void AActor::K2_DestroyActor()
{
static auto DestroyActorFn = FindObject<UFunction>("/Script/Engine.Actor.K2_DestroyActor");
this->ProcessEvent(DestroyActorFn);
}
UActorComponent* AActor::GetComponentByClass(class UClass* ComponentClass)
{
static auto fn = FindObject<UFunction>("/Script/Engine.Actor.GetComponentByClass");
struct
{
class UClass* ComponentClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UActorComponent* ReturnValue; // (ExportObject, Parm, OutParm, ZeroConstructor, ReturnParm, InstancedReference, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AActor_GetComponentByClass_Params{ComponentClass};
this->ProcessEvent(fn, &AActor_GetComponentByClass_Params);
return AActor_GetComponentByClass_Params.ReturnValue;
}
float AActor::GetDistanceTo(AActor* OtherActor)
{
static auto fn = FindObject<UFunction>("/Script/Engine.Actor.GetDistanceTo");
struct { AActor* OtherActor; float ReturnValue; } AActor_GetDistanceTo_Params{OtherActor};
this->ProcessEvent(fn, &AActor_GetDistanceTo_Params);
return AActor_GetDistanceTo_Params.ReturnValue;
}
FVector AActor::GetActorScale3D()
{
static auto GetActorScale3DFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorScale3D");
FVector Scale3D;
this->ProcessEvent(GetActorScale3DFn, &Scale3D);
return Scale3D;
}
FVector AActor::GetActorLocation()
{
static auto K2_GetActorLocationFn = FindObject<UFunction>("/Script/Engine.Actor.K2_GetActorLocation");
FVector ret;
this->ProcessEvent(K2_GetActorLocationFn, &ret);
return ret;
}
FVector AActor::GetActorForwardVector()
{
static auto GetActorForwardVectorFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorForwardVector");
FVector ret;
this->ProcessEvent(GetActorForwardVectorFn, &ret);
return ret;
}
FVector AActor::GetActorRightVector()
{
static auto GetActorRightVectorFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorRightVector");
FVector ret;
this->ProcessEvent(GetActorRightVectorFn, &ret);
return ret;
}
FVector AActor::GetActorUpVector()
{
static auto GetActorUpVectorFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorUpVector");
FVector ret;
this->ProcessEvent(GetActorUpVectorFn, &ret);
return ret;
}
FRotator AActor::GetActorRotation()
{
static auto K2_GetActorRotationFn = FindObject<UFunction>(L"/Script/Engine.Actor.K2_GetActorRotation");
FRotator ret;
this->ProcessEvent(K2_GetActorRotationFn, &ret);
return ret;
}
void AActor::FlushNetDormancy()
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.Actor.FlushNetDormancy");
this->ProcessEvent(fn);
}
bool AActor::TeleportTo(const FVector& DestLocation, const FRotator& DestRotation)
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.Actor.K2_TeleportTo");
struct
{
struct FVector DestLocation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
struct FRotator DestRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
bool ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AActor_K2_TeleportTo_Params{DestLocation, DestRotation};
this->ProcessEvent(fn, &AActor_K2_TeleportTo_Params);
return AActor_K2_TeleportTo_Params.ReturnValue;
}
bool AActor::IsActorBeingDestroyed()
{
static auto bActorIsBeingDestroyedOffset = GetOffset("bActorIsBeingDestroyed");
static auto bActorIsBeingDestroyedFieldMask = GetFieldMask(GetProperty("bActorIsBeingDestroyed"));
return ReadBitfieldValue(bActorIsBeingDestroyedOffset, bActorIsBeingDestroyedFieldMask);
}
bool AActor::IsNetStartup()
{
static auto bNetStartupOffset = GetOffset("bNetStartup");
static auto bNetStartupFieldMask = GetFieldMask(GetProperty("bNetStartup"));
return ReadBitfieldValue(bNetStartupOffset, bNetStartupFieldMask);
}
void AActor::SetOwner(AActor* Owner)
{
static auto SetOwnerFn = FindObject<UFunction>(L"/Script/Engine.Actor.SetOwner");
this->ProcessEvent(SetOwnerFn, &Owner);
}
void AActor::ForceNetUpdate()
{
static auto ForceNetUpdateFn = FindObject<UFunction>(L"/Script/Engine.Actor.ForceNetUpdate");
this->ProcessEvent(ForceNetUpdateFn);
}
bool AActor::IsNetStartupActor()
{
return IsNetStartup(); // The implementation on this function depends on the version.
}
bool AActor::IsPendingKillPending()
{
return IsActorBeingDestroyed() || !IsValidChecked(this);
}
float& AActor::GetNetUpdateFrequency()
{
static auto NetUpdateFrequencyOffset = GetOffset("NetUpdateFrequency");
return Get<float>(NetUpdateFrequencyOffset);
}
float& AActor::GetMinNetUpdateFrequency()
{
static auto MinNetUpdateFrequencyOffset = GetOffset("MinNetUpdateFrequency");
return Get<float>(MinNetUpdateFrequencyOffset);
}
const AActor* AActor::GetNetOwner() const
{
static int GetNetOwnerOffset = 0x448; // 1.11
const AActor* (*GetNetOwnerOriginal)(const AActor*) = decltype(GetNetOwnerOriginal)(this->VFTable[GetNetOwnerOffset / 8]);
return GetNetOwnerOriginal(this);
}
void AActor::GetActorEyesViewPoint(FVector* OutLocation, FRotator* OutRotation) const
{
static auto GetActorEyesViewPointFn = FindObject<UFunction>(L"/Script/Engine.Actor.GetActorEyesViewPoint");
struct
{
FVector OutLocation; // (Parm, OutParm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FRotator OutRotation; // (Parm, OutParm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
} AActor_GetActorEyesViewPoint_Params{};
this->ProcessEvent(GetActorEyesViewPointFn, &AActor_GetActorEyesViewPoint_Params);
*OutLocation = AActor_GetActorEyesViewPoint_Params.OutLocation;
*OutRotation = AActor_GetActorEyesViewPoint_Params.OutRotation;
}
AActor* AActor::GetClosestActor(UClass* ActorClass, float DistMax, std::function<bool(AActor*)> AdditionalCheck)
{
float TargetDist = FLT_MAX;
AActor* TargetActor = nullptr;
TArray<AActor*> AllActors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), ActorClass);
auto ActorLocation = GetActorLocation();
for (int i = 0; i < AllActors.Num(); ++i)
{
auto Actor = AllActors.at(i);
if (!Actor || Actor == this)
continue;
if (!AdditionalCheck(Actor))
continue;
auto CurrentActorLocation = Actor->GetActorLocation();
int Dist = float(sqrtf(powf(CurrentActorLocation.X - ActorLocation.X, 2.0) + powf(CurrentActorLocation.Y - ActorLocation.Y, 2.0) + powf(CurrentActorLocation.Z - ActorLocation.Z, 2.0))) / 100.f;
if (Dist <= DistMax && Dist < TargetDist)
{
TargetDist = Dist;
TargetActor = Actor;
}
}
AllActors.Free();
return TargetActor;
}
bool AActor::IsAlwaysRelevant()
{
static auto bAlwaysRelevantOffset = GetOffset("bAlwaysRelevant");
static auto bAlwaysRelevantFieldMask = GetFieldMask(GetProperty("bAlwaysRelevant"));
return ReadBitfieldValue(bAlwaysRelevantOffset, bAlwaysRelevantFieldMask);
}
bool AActor::UsesOwnerRelevancy()
{
static auto bNetUseOwnerRelevancyOffset = GetOffset("bNetUseOwnerRelevancy");
static auto bNetUseOwnerRelevancyFieldMask = GetFieldMask(GetProperty("bNetUseOwnerRelevancy"));
return ReadBitfieldValue(bNetUseOwnerRelevancyOffset, bNetUseOwnerRelevancyFieldMask);
}
bool AActor::IsOnlyRelevantToOwner()
{
static auto bOnlyRelevantToOwnerOffset = GetOffset("bOnlyRelevantToOwner");
static auto bOnlyRelevantToOwnerFieldMask = GetFieldMask(GetProperty("bOnlyRelevantToOwner"));
return ReadBitfieldValue(bOnlyRelevantToOwnerOffset, bOnlyRelevantToOwnerFieldMask);
}
bool AActor::CanBeDamaged()
{
static auto bCanBeDamagedOffset = GetOffset("bCanBeDamaged");
static auto bCanBeDamagedFieldMask = GetFieldMask(GetProperty("bCanBeDamaged"));
return ReadBitfieldValue(bCanBeDamagedOffset, bCanBeDamagedFieldMask);
}
void AActor::SetCanBeDamaged(bool NewValue)
{
static auto bCanBeDamagedOffset = GetOffset("bCanBeDamaged");
static auto bCanBeDamagedFieldMask = GetFieldMask(GetProperty("bCanBeDamaged"));
SetBitfieldValue(bCanBeDamagedOffset, bCanBeDamagedFieldMask, NewValue);
}
UClass* AActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.Actor");
return Class;
}

View File

@@ -1,70 +0,0 @@
#pragma once
#include "Object.h"
#include "anticheat.h"
enum class ENetDormancy : uint8_t
{
DORM_Never = 0,
DORM_Awake = 1,
DORM_DormantAll = 2,
DORM_DormantPartial = 3,
DORM_Initial = 4,
DORN_MAX = 5,
ENetDormancy_MAX = 6
};
class AActor : public UObject
{
public:
struct FTransform GetTransform();
// class UWorld* GetWorld();
bool HasAuthority();
bool IsTearOff();
/* FORCEINLINE */ ENetDormancy& GetNetDormancy();
int32& GetNetTag();
void SetNetDormancy(ENetDormancy Dormancy);
AActor* GetOwner();
struct FVector GetActorScale3D();
struct FVector GetActorLocation();
struct FVector GetActorForwardVector();
struct FVector GetActorRightVector();
struct FVector GetActorUpVector();
void K2_DestroyActor();
class UActorComponent* GetComponentByClass(class UClass* ComponentClass);
float GetDistanceTo(AActor* OtherActor);
struct FRotator GetActorRotation();
void FlushNetDormancy();
bool TeleportTo(const FVector& DestLocation, const FRotator& DestRotation);
bool IsActorBeingDestroyed();
bool IsNetStartup();
bool IsAlwaysRelevant();
bool UsesOwnerRelevancy();
bool IsOnlyRelevantToOwner();
bool CanBeDamaged();
void SetCanBeDamaged(bool NewValue);
void SetOwner(AActor* Owner);
void ForceNetUpdate();
bool IsNetStartupActor();
bool IsPendingKillPending();
float& GetNetUpdateFrequency();
float& GetMinNetUpdateFrequency();
const AActor* GetNetOwner() const;
void GetActorEyesViewPoint(FVector* OutLocation, FRotator* OutRotation) const;
AActor* GetClosestActor(UClass* ActorClass, float DistMax, std::function<bool(AActor*)> AdditionalCheck = [&](AActor*) { return true; });
bool IsRelevancyOwnerFor(const AActor* ReplicatedActor, const AActor* ActorOwner, const AActor* ConnectionActor) const
{
// we should call virtual function but eh
// return (ActorOwner == this);
static auto IsRelevancyOwnerForOffset = 0x428;
bool (*IsRelevancyOwnerForOriginal)(const AActor* Actor, const AActor * ReplicatedActor, const AActor * ActorOwner, const AActor * ConnectionActor) =
decltype(IsRelevancyOwnerForOriginal)(this->VFTable[IsRelevancyOwnerForOffset / 8]);
return IsRelevancyOwnerForOriginal(this, ReplicatedActor, ActorOwner, ConnectionActor);
}
static class UClass* StaticClass();
};

View File

@@ -1,32 +0,0 @@
#pragma once
#include "Channel.h"
#include "NetworkGuid.h"
class UActorChannel : public UChannel
{
public:
double& GetLastUpdateTime()
{
static auto LastUpdateTimeOffset = GetOffset("Actor") + 8 + 4 + 4 + 8; // checked on 4.19
return Get<double>(LastUpdateTimeOffset);
}
double& GetRelevantTime()
{
static auto RelevantTimeOffset = GetOffset("Actor") + 8 + 4 + 4; // checked on 4.19
return Get<double>(RelevantTimeOffset);
}
AActor*& GetActor()
{
static auto ActorOffset = GetOffset("Actor");
return Get<AActor*>(ActorOffset);
}
void Close()
{
static void (*ActorChannelClose)(UActorChannel*) = decltype(ActorChannelClose)(Addresses::ActorChannelClose);
ActorChannelClose(this);
}
};

View File

@@ -1,11 +0,0 @@
#include "ActorComponent.h"
#include "reboot.h"
AActor* UActorComponent::GetOwner()
{
auto GetOwnerFn = FindObject<UFunction>(L"/Script/Engine.ActorComponent.GetOwner");
AActor* Owner;
this->ProcessEvent(GetOwnerFn, &Owner);
return Owner;
}

View File

@@ -1,9 +0,0 @@
#pragma once
#include "Actor.h"
class UActorComponent : public UObject
{
public:
AActor* GetOwner();
};

View File

@@ -1,73 +0,0 @@
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "inc.h"
/**
* Does a boolean AND of the ::Value static members of each type, but short-circuits if any Type::Value == false.
*/
template <typename... Types>
struct TAnd;
template <bool LHSValue, typename... RHS>
struct TAndValue
{
enum { Value = TAnd<RHS...>::Value };
};
template <typename... RHS>
struct TAndValue<false, RHS...>
{
enum { Value = false };
};
template <typename LHS, typename... RHS>
struct TAnd<LHS, RHS...> : TAndValue<LHS::Value, RHS...>
{
};
template <>
struct TAnd<>
{
enum { Value = true };
};
/**
* Does a boolean OR of the ::Value static members of each type, but short-circuits if any Type::Value == true.
*/
template <typename... Types>
struct TOr;
template <bool LHSValue, typename... RHS>
struct TOrValue
{
enum { Value = TOr<RHS...>::Value };
};
template <typename... RHS>
struct TOrValue<true, RHS...>
{
enum { Value = true };
};
template <typename LHS, typename... RHS>
struct TOr<LHS, RHS...> : TOrValue<LHS::Value, RHS...>
{
};
template <>
struct TOr<>
{
enum { Value = false };
};
/**
* Does a boolean NOT of the ::Value static members of the type.
*/
template <typename Type>
struct TNot
{
enum { Value = !Type::Value };
};

View File

@@ -1,415 +0,0 @@
#pragma once
#include "inc.h"
#include "addresses.h"
#include "MemoryOps.h"
#include "ContainerAllocationPolicies.h"
struct FMemory
{
static inline void* (*Realloc)(void* Original, SIZE_T Count, uint32_t Alignment /* = DEFAULT_ALIGNMENT */);
};
template <typename T = __int64>
static T* AllocUnreal(size_t Size)
{
return (T*)FMemory::Realloc(0, Size, 0);
}
template<typename InElementType> //, typename InAllocatorType>
class TArray
{
// protected:
public:
friend class FString;
using ElementAllocatorType = InElementType*;
using SizeType = int32;
ElementAllocatorType Data = nullptr; // AllocatorInstance;
SizeType ArrayNum;
SizeType ArrayMax;
public:
inline InElementType& At(int i, size_t Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType& at(int i, size_t Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType* AtPtr(int i, size_t Size = sizeof(InElementType)) const { return (InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
bool IsValidIndex(int i) { return i > 0 && i < ArrayNum; }
ElementAllocatorType& GetData() const { return Data; }
ElementAllocatorType& GetData() { return Data; }
void Reserve(int Number, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogDev, "ArrayNum {}", ArrayNum);
// Data = (InElementType*)FMemory::Realloc(Data, (ArrayMax = ArrayNum + Number) * Size, 0);
Data = /* (ArrayMax - ArrayNum) >= ArrayNum ? Data : */ (InElementType*)FMemory::Realloc(Data, (ArrayMax = Number + ArrayNum) * Size, 0);
}
int CalculateSlackReserve(SizeType NumElements, SIZE_T NumBytesPerElement) const
{
return DefaultCalculateSlackReserve(NumElements, NumBytesPerElement, false);
}
void ResizeArray(SizeType NewNum, SIZE_T NumBytesPerElement)
{
const SizeType CurrentMax = ArrayMax;
SizeType v3 = NewNum;
if (NewNum)
{
/* SizeType v6 = (unsigned __int64)FMemory::QuantizeSize(4 * NewNum, 0) >> 2;
// if (v3 > (int)v6)
// LODWORD(v6) = 0x7FFFFFFF;
v3 = v6; */
}
if (v3 != CurrentMax && (Data || v3))
Data = (InElementType*)FMemory::Realloc(Data, NumBytesPerElement * v3, 0);
ArrayNum = v3; // ?
ArrayMax = v3;
}
void RefitArray(SIZE_T NumBytesPerElement = sizeof(InElementType))
{
auto newNum = ArrayNum;
// newNum = FMemory::QuantizeSize(NumBytesPerElement * newNum, 0) >> 4
ArrayMax = newNum;
if (Data || ArrayNum)
{
Data = false ? (InElementType*)VirtualAlloc(0, newNum * NumBytesPerElement, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) :
(InElementType*)FMemory::Realloc(Data, newNum * NumBytesPerElement, 0);
}
}
int AddUninitialized2(SIZE_T NumBytesPerElement = sizeof(InElementType))
{
const int OldArrayNum = ArrayNum;
ArrayNum = OldArrayNum + 1;
if (OldArrayNum + 1 > ArrayMax)
{
RefitArray(NumBytesPerElement);
// ResizeArray(ArrayNum, NumBytesPerElement);
}
return OldArrayNum;
}
void CopyFromArray(TArray<InElementType>& OtherArray, SIZE_T NumBytesPerElement = sizeof(InElementType))
{
if (!OtherArray.ArrayNum && !ArrayMax) // so if the new array has nothing, and we currently have nothing allocated, then we can just return
{
ArrayMax = 0;
return;
}
ResizeArray(OtherArray.ArrayNum, NumBytesPerElement);
memcpy(this->Data, OtherArray.Data, NumBytesPerElement * OtherArray.ArrayNum);
}
/*
FORCENOINLINE void ResizeForCopy(SizeType NewMax, SizeType PrevMax, int ElementSize = sizeof(InElementType))
{
if (NewMax)
{
NewMax = CalculateSlackReserve(NewMax, ElementSize);
}
if (NewMax != PrevMax)
{
int ReserveCount = NewMax - PrevMax; // IDK TODO Milxnor
Reserve(ReserveCount, ElementSize);
// AllocatorInstance.ResizeAllocation(0, NewMax, ElementSize);
}
ArrayMax = NewMax;
}
template <typename OtherElementType, typename OtherSizeType>
void CopyToEmpty(const OtherElementType* OtherData, OtherSizeType OtherNum, SizeType PrevMax, SizeType ExtraSlack, int ElementSize = sizeof(InElementType))
{
SizeType NewNum = (SizeType)OtherNum;
// checkf((OtherSizeType)NewNum == OtherNum, TEXT("Invalid number of elements to add to this array type: %llu"), (unsigned long long)NewNum);
// checkSlow(ExtraSlack >= 0);
ArrayNum = NewNum;
if (OtherNum || ExtraSlack || PrevMax)
{
ResizeForCopy(NewNum + ExtraSlack, PrevMax);
ConstructItems<InElementType>(GetData(), OtherData, OtherNum);
}
else
{
ArrayMax = 0; // AllocatorInstance.GetInitialCapacity();
}
}
FORCEINLINE TArray(const TArray& Other)
{
CopyToEmpty(Other.Data, Other.Num(), 0, 0);
}
*/
TArray() : Data(nullptr), ArrayNum(0), ArrayMax(0) {}
inline int Num() const { return ArrayNum; }
inline int size() const { return ArrayNum; }
/* FORCENOINLINE void ResizeTo(int32 NewMax)
{
if (NewMax)
{
NewMax = AllocatorInstance.CalculateSlackReserve(NewMax, sizeof(ElementType));
}
if (NewMax != ArrayMax)
{
ArrayMax = NewMax;
AllocatorInstance.ResizeAllocation(ArrayNum, ArrayMax, sizeof(ElementType));
}
}
void Empty(int32 Slack = 0)
{
// DestructItems(GetData(), ArrayNum);
// checkSlow(Slack >= 0);
ArrayNum = 0;
if (ArrayMax != Slack)
{
ResizeTo(Slack);
}
}
void Reset(int32 NewSize = 0)
{
// If we have space to hold the excepted size, then don't reallocate
if (NewSize <= ArrayMax)
{
// DestructItems(GetData(), ArrayNum);
ArrayNum = 0;
}
else
{
Empty(NewSize);
}
} */
void RemoveAtImpl(int32 Index, int32 Count, bool bAllowShrinking)
{
if (Count)
{
// CheckInvariants();
// checkSlow((Count >= 0) & (Index >= 0) & (Index + Count <= ArrayNum));
// DestructItems(GetData() + Index, Count); // TODO milxnor
// Skip memmove in the common case that there is nothing to move.
int32 NumToMove = ArrayNum - Index - Count;
if (NumToMove)
{
/* FMemory::Memmove
(
(uint8*)AllocatorInstance.GetAllocation() + (Index) * sizeof(ElementType),
(uint8*)AllocatorInstance.GetAllocation() + (Index + Count) * sizeof(ElementType),
NumToMove * sizeof(ElementType)
); */
// memmove(Data + (Index) * sizeof(InElementType), Data + (Index + Count) * sizeof(InElementType), NumToMove * sizeof(InElementType)); // i think this wrong
}
ArrayNum -= Count;
if (bAllowShrinking)
{
// ResizeShrink(); // TODO milxnor
}
}
}
FORCEINLINE SizeType CalculateSlackGrow(SizeType NumElements, SizeType NumAllocatedElements, SIZE_T NumBytesPerElement) const
{
return ArrayMax - NumElements;
}
template <typename CountType>
FORCEINLINE void RemoveAt(int32 Index, CountType Count, bool bAllowShrinking = true)
{
// static_assert(!TAreTypesEqual<CountType, bool>::Value, "TArray::RemoveAt: unexpected bool passed as the Count argument");
RemoveAtImpl(Index, Count, bAllowShrinking);
}
FORCENOINLINE void ResizeGrow(int32 OldNum, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogMemory, "FMemory::Realloc: {}", __int64(FMemory::Realloc));
ArrayMax = ArrayNum; // CalculateSlackGrow(/* ArrayNum */ OldNum, ArrayMax, Size);
// AllocatorInstance.ResizeAllocation(OldNum, ArrayMax, sizeof(ElementType));
// LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size);
Data = (InElementType*)FMemory::Realloc(Data, ArrayNum * Size, 0);
}
FORCEINLINE int32 AddUninitialized(int32 Count = 1, size_t Size = sizeof(InElementType))
{
// CheckInvariants();
if (Count < 0)
{
return 0;
}
const int32 OldNum = ArrayNum;
if ((ArrayNum += Count) > ArrayMax)
{
ResizeGrow(OldNum, Size);
}
return OldNum;
}
FORCEINLINE int32 Emplace(const InElementType& New, size_t Size = sizeof(InElementType))
{
const int32 Index = AddUninitialized(1, Size); // resizes array
memcpy_s((InElementType*)(__int64(Data) + (Index * Size)), Size, (void*)&New, Size);
// new(GetData() + Index) ElementType(Forward<ArgsType>(Args)...);
return Index;
}
/* int Add(const InElementType& New, int Size = sizeof(InElementType))
{
return Emplace(New, Size);
} */
int AddPtr(InElementType* New, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax);
if ((ArrayNum + 1) > ArrayMax)
{
Reserve(1, Size);
}
if (Data)
{
memcpy_s((InElementType*)(__int64(Data) + (ArrayNum * Size)), Size, (void*)New, Size);
++ArrayNum;
return ArrayNum; // - 1;
}
return -1;
}
int Add(const InElementType& New, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax);
if ((ArrayNum + 1) > ArrayMax)
{
Reserve(1, Size);
}
if (Data)
{
memcpy_s((InElementType*)(__int64(Data) + (ArrayNum * Size)), Size, (void*)&New, Size);
++ArrayNum;
return ArrayNum; // - 1;
}
return -1;
}
void FreeGood(SizeType Size = sizeof(InElementType))
{
if (Data)
{
if (true)
{
static void (*FreeOriginal)(void* Original) = decltype(FreeOriginal)(Addresses::Free);
if (FreeOriginal)
FreeOriginal(Data);
}
else
{
VirtualFree(Data, 0, MEM_RELEASE);
}
}
Data = nullptr;
ArrayNum = 0;
ArrayMax = 0;
}
void FreeReal(SizeType Size = sizeof(InElementType))
{
if (!IsBadReadPtr(Data, 8) && ArrayNum > 0 && sizeof(InElementType) > 0)
{
for (int i = 0; i < ArrayNum; ++i)
{
auto current = AtPtr(i, Size);
RtlSecureZeroMemory(current, Size);
}
// VirtualFree(Data, _msize(Data), MEM_RELEASE);
// VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE); // ik this does nothing
/* static void (*FreeOriginal)(void*) = decltype(FreeOriginal)(Addresses::Free);
if (FreeOriginal)
{
FreeOriginal(Data);
}
else */
{
auto res = VirtualFree(Data, 0, MEM_RELEASE);
// auto res = VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE);
LOG_INFO(LogDev, "Free: {} aa: 0x{:x}", res, res ? 0 : GetLastError());
}
}
Data = nullptr;
ArrayNum = 0;
ArrayMax = 0;
}
void Free()
{
if (Data && ArrayNum > 0 && sizeof(InElementType) > 0)
{
// VirtualFree(Data, _msize(Data), MEM_RELEASE);
VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE); // ik this does nothing
// VirtualFree(Data, 0, MEM_RELEASE);
}
Data = nullptr;
ArrayNum = 0;
ArrayMax = 0;
}
bool Remove(const int Index, size_t Size = sizeof(InElementType))
{
// return false;
if (Index < ArrayNum)
{
if (Index != ArrayNum - 1)
{
memcpy_s(&at(Index, Size), Size, &at(ArrayNum - 1, Size), Size);
// Data[Index] = Data[ArrayNum - 1];
}
--ArrayNum;
return true;
}
return false;
}
};

View File

@@ -1,61 +0,0 @@
#pragma once
#include "log.h"
#include "inc.h"
/*
#ifdef PROD
#define UE_DEBUG_BREAK() ((void)0)
#else
#define UE_DEBUG_BREAK() ((void)(FWindowsPlatformMisc::IsDebuggerPresent() && (__debugbreak(), 1)))
#endif
#ifndef PROD
#define _DebugBreakAndPromptForRemote() \
if (!FPlatformMisc::IsDebuggerPresent()) { FPlatformMisc::PromptForRemoteDebugging(false); } UE_DEBUG_BREAK();
#else
#define _DebugBreakAndPromptForRemote()
#endif
#define CA_ASSUME( Expr ) // Todo move to Misc/CoreMiscDefines.h
namespace FDebug
{
template <typename FmtType, typename... Types>
static void LogAssertFailedMessage(const char* Expr, const char* File, int32 Line, const FmtType& Fmt, Types... Args)
{
// static_assert(TIsArrayOrRefOfType<FmtType, TCHAR>::Value, "Formatting string must be a TCHAR array.");
// tatic_assert(TAnd<TIsValidVariadicFunctionArg<Types>...>::Value, "Invalid argument(s) passed to FDebug::LogAssertFailedMessage");
LOG_ERROR(LogDev, "Assert failed message {} {}", File, Line);
// LogAssertFailedMessageImpl(Expr, File, Line, Fmt, Args...);
}
void __cdecl AssertFailed(const char* Expr, const char* File, int32 Line, const wchar_t* Format = TEXT(""), ...)
{
LOG_ERROR(LogDev, "Assert failed {} {}", File, Line);
/*
if (GIsCriticalError)
{
return;
}
// This is not perfect because another thread might crash and be handled before this assert
// but this static varible will report the crash as an assert. Given complexity of a thread
// aware solution, this should be good enough. If crash reports are obviously wrong we can
// look into fixing this.
bHasAsserted = true;
TCHAR DescriptionString[4096];
GET_VARARGS(DescriptionString, ARRAY_COUNT(DescriptionString), ARRAY_COUNT(DescriptionString) - 1, Format, Format);
TCHAR ErrorString[MAX_SPRINTF];
FCString::Sprintf(ErrorString, TEXT("%s"), ANSI_TO_TCHAR(Expr));
GError->Logf(TEXT("Assertion failed: %s") FILE_LINE_DESC TEXT("\n%s\n"), ErrorString, ANSI_TO_TCHAR(File), Line, DescriptionString);
}
}
*/
// #define check(expr) { if(UNLIKELY(!(expr))) { FDebug::LogAssertFailedMessage( #expr, __FILE__, __LINE__, TEXT("") ); _DebugBreakAndPromptForRemote(); FDebug::AssertFailed( #expr, __FILE__, __LINE__ ); CA_ASSUME(false); } }

View File

@@ -1,26 +0,0 @@
#pragma once
#include "PersistentObjectPtr.h"
#include "StringAssetReference.h"
#include "reboot.h"
class FAssetPtr : public TPersistentObjectPtr<FStringAssetReference>
{
public:
};
template<class T = UObject>
class TAssetPtr
{
public:
FAssetPtr AssetPtr;
T* Get()
{
if (!AssetPtr.ObjectID.AssetLongPathname.IsValid())
return nullptr;
return FindObject<T>(AssetPtr.ObjectID.AssetLongPathname.ToString());
}
};

View File

@@ -1,44 +0,0 @@
#pragma once
#include "BuildingGameplayActor.h"
#include "AthenaBarrierObjective.h"
struct FBarrierFlagDisplayData
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.BarrierFlagDisplayData");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UStaticMesh* GetHeadMesh()
{
static auto HeadMeshOffset = FindOffsetStruct("/Script/FortniteGame.BarrierFlagDisplayData", "HeadMesh");
return *(UStaticMesh**)(__int64(this) + HeadMeshOffset);
}
FVector& GetMeshScale()
{
static auto MeshScaleOffset = FindOffsetStruct("/Script/FortniteGame.BarrierFlagDisplayData", "MeshScale");
return *(FVector*)(__int64(this) + MeshScaleOffset);
}
};
class AAthenaBarrierFlag : public ABuildingGameplayActor
{
public:
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = GetOffset("FoodTeam");
return Get<EBarrierFoodTeam>(FoodTeamOffset);
}
FBarrierFlagDisplayData* GetDisplayData(EBarrierFoodTeam FoodTeam)
{
static auto FoodDisplayDataOffset = GetOffset("FoodDisplayData");
auto FoodDisplayData = Get<FBarrierFlagDisplayData*>(FoodDisplayDataOffset); // Array of size 2
return &FoodDisplayData[(int)FoodTeam];
}
};

View File

@@ -1,59 +0,0 @@
#pragma once
#include "BuildingGameplayActor.h"
using UStaticMesh = UObject;
using UMaterialInterface = UObject;
enum class EBarrierFoodTeam : uint8_t
{
Burger = 0,
Tomato = 1,
MAX = 2
};
struct FBarrierObjectiveDisplayData
{
UStaticMesh* HeadMesh; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector MeshScale; // 0x0008(0x000C) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector MeshRelativeOffset; // 0x0014(0x000C) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<UMaterialInterface*> MaterialsToSwap; // 0x0020(0x0010) (Edit, ZeroConstructor, NativeAccessSpecifierPublic)
};
class AAthenaBarrierObjective : public ABuildingGameplayActor
{
public:
void SetHeadMesh(UStaticMesh* NewMesh, const FVector& NewScale, const FVector& NewOffset, const TArray<UMaterialInterface*>& MaterialsToSwap)
{
static auto SetHeadMeshFn = FindObject<UFunction>("/Script/FortniteGame.AthenaBarrierObjective.SetHeadMesh");
struct
{
UStaticMesh* NewMesh; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector NewScale; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector NewOffset; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<UMaterialInterface*> MaterialsToSwap; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, NativeAccessSpecifierPublic)
} AAthenaBarrierObjective_SetHeadMesh_Params{ NewMesh, NewScale, NewOffset, MaterialsToSwap };
this->ProcessEvent(SetHeadMeshFn, &AAthenaBarrierObjective_SetHeadMesh_Params);
}
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = GetOffset("FoodTeam");
return Get<EBarrierFoodTeam>(FoodTeamOffset);
}
FBarrierObjectiveDisplayData* GetFoodDisplayData(EBarrierFoodTeam FoodTeam)
{
static auto FoodDisplayDataOffset = GetOffset("FoodDisplayData");
auto FoodDisplayData = Get<FBarrierObjectiveDisplayData*>(FoodDisplayDataOffset); // Array size of 2
return &FoodDisplayData[(int)FoodTeam];
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.AthenaBarrierObjective");
return Class;
}
};

View File

@@ -1,8 +0,0 @@
#pragma once
#include "BuildingGameplayActor.h"
class AAthenaBigBaseWall : public ABuildingGameplayActor
{
public:
};

View File

@@ -1,161 +0,0 @@
#include "AthenaMarkerComponent.h"
#include "FortPlayerControllerAthena.h"
#include "Text.h"
#include "KismetTextLibrary.h"
void UAthenaMarkerComponent::ServerAddMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FFortClientMarkerRequest MarkerRequest)
{
auto Owner = MarkerComponent->GetOwner();
AFortPlayerControllerAthena* PlayerController = Cast<AFortPlayerControllerAthena>(Owner);
if (!PlayerController)
return;
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerState)
return;
auto MarkerRequestPtr = &MarkerRequest;
bool useRealloc = false;
auto MarkerData = Alloc<FFortWorldMarkerData>(FFortWorldMarkerData::GetStructSize(), useRealloc);
static auto IconOffset = FindOffsetStruct("/Script/FortniteGame.MarkedActorDisplayInfo", "Icon");
static auto DisplayNameOffset = FindOffsetStruct("/Script/FortniteGame.MarkedActorDisplayInfo", "DisplayName");
static auto WorldPositionOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPosition", false);
static auto bIncludeSquadOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "bIncludeSquad", false);
static auto WorldPositionOffsetOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPositionOffset", false);
FMarkerID MarkerID{};
MarkerID.PlayerID = PlayerState->GetPlayerID();
MarkerID.InstanceID = MarkerRequestPtr->GetInstanceID();
MarkerData->GetMarkerType() = MarkerRequestPtr->GetMarkerType();
MarkerData->GetOwner() = PlayerState;
MarkerData->GetWorldNormal() = MarkerRequestPtr->GetWorldNormal();
if (WorldPositionOffset != -1)
MarkerData->GetWorldPosition() = MarkerRequestPtr->GetWorldPosition();
if (WorldPositionOffset != -1)
MarkerData->GetWorldPositionOffset() = MarkerRequestPtr->GetWorldPositionOffset();
if (bIncludeSquadOffset != -1)
MarkerData->DoesIncludeSquad() = MarkerRequestPtr->DoesIncludeSquad();
MarkerData->GetMarkerID() = MarkerID;
MarkerData->GetMarkedActorClass().SoftObjectPtr.WeakPtr.ObjectIndex = -1;
MarkerData->GetMarkedActorClass().SoftObjectPtr.TagAtLastTest = 0;
MarkerData->GetMarkedActorClass().SoftObjectPtr.WeakPtr.ObjectSerialNumber = 0;
MarkerData->GetMarkedActor().SoftObjectPtr.WeakPtr.ObjectIndex = -1;
MarkerData->GetMarkedActor().SoftObjectPtr.TagAtLastTest = 0;
MarkerData->GetMarkedActor().SoftObjectPtr.WeakPtr.ObjectSerialNumber = 0;
((TSoftObjectPtr<UObject>*)(__int64(MarkerData->GetCustomDisplayInfo()) + IconOffset))->SoftObjectPtr.WeakPtr.ObjectIndex = -1;
((TSoftObjectPtr<UObject>*)(__int64(MarkerData->GetCustomDisplayInfo()) + IconOffset))->SoftObjectPtr.TagAtLastTest = 0;
((TSoftObjectPtr<UObject>*)(__int64(MarkerData->GetCustomDisplayInfo()) + IconOffset))->SoftObjectPtr.WeakPtr.ObjectSerialNumber = 0;
*(FText*)(__int64(MarkerData->GetCustomDisplayInfo()) + DisplayNameOffset) = UKismetTextLibrary::Conv_StringToText(L"");
static auto PlayerTeamOffset = PlayerState->GetOffset("PlayerTeam");
auto PlayerTeam = PlayerState->Get<UObject*>(PlayerTeamOffset);
if (!PlayerTeam)
return;
static auto TeamMembersOffset = PlayerTeam->GetOffset("TeamMembers");
auto& TeamMembers = PlayerTeam->Get<TArray<AController*>>(TeamMembersOffset);
for (int i = 0; i < TeamMembers.Num(); ++i)
{
if (TeamMembers.at(i) == PlayerController)
continue;
auto CurrentTeamMemberPC = Cast<AFortPlayerControllerAthena>(TeamMembers.at(i));
if (!CurrentTeamMemberPC)
continue;
auto CurrentTeamMemberMarkerComponent = CurrentTeamMemberPC->GetMarkerComponent();// (UAthenaMarkerComponent*)CurrentTeamMemberPC->GetComponentByClass(UAthenaMarkerComponent::StaticClass());
if (!CurrentTeamMemberMarkerComponent)
continue;
static auto ClientAddMarkerFn = FindObject<UFunction>(L"/Script/FortniteGame.AthenaMarkerComponent.ClientAddMarker");
if (ClientAddMarkerFn)
{
CurrentTeamMemberMarkerComponent->ProcessEvent(ClientAddMarkerFn, MarkerData);
}
else
{
// We are assuming it is not the TArray and it is FFortWorldMarkerContainer
static auto MarkerStreamOffset = CurrentTeamMemberMarkerComponent->GetOffset("MarkerStream");
auto MarkerStream = CurrentTeamMemberMarkerComponent->GetPtr<FFastArraySerializer>(MarkerStreamOffset);
static auto MarkersOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerContainer", "Markers");
if (MarkersOffset != -1)
{
// We are assuming it is a FFastArraySerializerItem
((FFastArraySerializerItem*)MarkerData)->MostRecentArrayReplicationKey = -1;
((FFastArraySerializerItem*)MarkerData)->ReplicationID = -1;
((FFastArraySerializerItem*)MarkerData)->ReplicationKey = -1;
auto Markers = (TArray<FFortWorldMarkerData>*)(__int64(MarkerStream) + MarkersOffset);
Markers->AddPtr(MarkerData, FFortWorldMarkerData::GetStructSize());
MarkerStream->MarkArrayDirty();
}
}
}
}
void UAthenaMarkerComponent::ServerRemoveMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FMarkerID MarkerID, uint8_t CancelReason)
{
auto Owner = MarkerComponent->GetOwner();
AFortPlayerControllerAthena* PlayerController = Cast<AFortPlayerControllerAthena>(Owner);
if (!PlayerController)
return;
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerState)
return;
static auto PlayerTeamOffset = PlayerState->GetOffset("PlayerTeam");
auto PlayerTeam = PlayerState->Get<UObject*>(PlayerTeamOffset);
if (!PlayerTeam)
return;
static auto TeamMembersOffset = PlayerTeam->GetOffset("TeamMembers");
auto& TeamMembers = PlayerTeam->Get<TArray<AController*>>(TeamMembersOffset);
for (int i = 0; i < TeamMembers.Num(); ++i)
{
if (TeamMembers.at(i) == PlayerController)
continue;
auto CurrentTeamMemberPC = Cast<AFortPlayerControllerAthena>(TeamMembers.at(i));
if (!CurrentTeamMemberPC)
continue;
auto CurrentTeamMemberMarkerComponent = CurrentTeamMemberPC->GetMarkerComponent();
if (!CurrentTeamMemberMarkerComponent)
continue;
static auto ClientCancelMarkerFn = FindObject<UFunction>("/Script/FortniteGame.AthenaMarkerComponent.ClientCancelMarker");
if (ClientCancelMarkerFn)
{
CurrentTeamMemberMarkerComponent->ProcessEvent(ClientCancelMarkerFn, &MarkerID);
}
else
{
// UnmarkActorOnClient ?
}
}
}

View File

@@ -1,141 +0,0 @@
#pragma once
#include "ActorComponent.h"
#include "Vector.h"
#include "SoftObjectPtr.h"
#include "FortPlayerState.h"
struct FMarkerID { int PlayerID; int InstanceID; };
struct FFortClientMarkerRequest
{
char pad[0x20]; // real idk
int& GetInstanceID()
{
static auto InstanceIDOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "InstanceID", false) == -1 ?
FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "InstanceId") : FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "InstanceID");
return *(int*)(__int64(this) + InstanceIDOffset);
}
bool& DoesIncludeSquad()
{
static auto bIncludeSquadOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "bIncludeSquad");
return *(bool*)(__int64(this) + bIncludeSquadOffset);
}
bool& UsesHoveredMarkerDetail()
{
static auto bUseHoveredMarkerDetailOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "bUseHoveredMarkerDetail");
return *(bool*)(__int64(this) + bUseHoveredMarkerDetailOffset);
}
FVector& GetWorldPosition()
{
static auto WorldPositionOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "WorldPosition");
return *(FVector*)(__int64(this) + WorldPositionOffset);
}
uint8_t& GetMarkerType()
{
static auto MarkerTypeOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "MarkerType");
return *(uint8_t*)(__int64(this) + MarkerTypeOffset);
}
FVector& GetWorldPositionOffset()
{
static auto WorldPositionOffsetOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "WorldPositionOffset");
return *(FVector*)(__int64(this) + WorldPositionOffsetOffset);
}
FVector& GetWorldNormal()
{
static auto WorldNormalOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "WorldNormal");
return *(FVector*)(__int64(this) + WorldNormalOffset);
}
};
struct FFortWorldMarkerData
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.FortWorldMarkerData");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
FMarkerID& GetMarkerID()
{
static auto MarkerIDOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkerID");
return *(FMarkerID*)(__int64(this) + MarkerIDOffset);
}
UObject*& GetMarkerInstance()
{
static auto MarkerInstanceOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkerInstance");
return *(UObject**)(__int64(this) + MarkerInstanceOffset);
}
FVector& GetWorldPosition()
{
static auto WorldPositionOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPosition");
return *(FVector*)(__int64(this) + WorldPositionOffset);
}
bool& DoesIncludeSquad()
{
static auto bIncludeSquadOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "bIncludeSquad");
return *(bool*)(__int64(this) + bIncludeSquadOffset);
}
FVector& GetWorldPositionOffset()
{
static auto WorldPositionOffsetOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPositionOffset");
return *(FVector*)(__int64(this) + WorldPositionOffsetOffset);
}
FVector& GetWorldNormal()
{
static auto WorldNormalOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldNormal");
return *(FVector*)(__int64(this) + WorldNormalOffset);
}
TSoftObjectPtr<AActor>& GetMarkedActor()
{
static auto MarkedActorOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkedActor");
return *(TSoftObjectPtr<AActor>*)(__int64(this) + MarkedActorOffset);
}
uint8_t& GetMarkerType()
{
static auto MarkerTypeOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkerType");
return *(uint8_t*)(__int64(this) + MarkerTypeOffset);
}
TSoftObjectPtr<UClass>& GetMarkedActorClass()
{
static auto MarkedActorClassOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkedActorClass");
return *(TSoftObjectPtr<UClass>*)(__int64(this) + MarkedActorClassOffset);
}
AFortPlayerState*& GetOwner()
{
static auto OwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "Owner");
return *(AFortPlayerState**)(__int64(this) + OwnerOffset);
}
void* GetCustomDisplayInfo()
{
static auto CustomDisplayInfoOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "CustomDisplayInfo");
return (void*)(__int64(this) + CustomDisplayInfoOffset);
}
};
class UAthenaMarkerComponent : public UActorComponent
{
public:
static void ServerAddMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FFortClientMarkerRequest MarkerRequest);
static void ServerRemoveMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FMarkerID MarkerID, uint8_t CancelReason);
};

View File

@@ -1,55 +0,0 @@
#pragma once
#include "reboot.h"
struct FAthenaMatchTeamStats
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.AthenaMatchTeamStats");
return Struct;
}
static auto GetStructSize() { return GetStruct()->GetPropertiesSize(); }
int Place; // 0x0000(0x0004) (Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int TotalPlayers; // 0x0004(0x0004) (Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int& GetPlace()
{
return Place;
}
int& GetTotalPlayers()
{
return TotalPlayers;
}
};
class UAthenaPlayerMatchReport : public UObject
{
public:
bool& HasTeamStats()
{
static auto bHasTeamStatsOffset = GetOffset("bHasTeamStats");
return Get<bool>(bHasTeamStatsOffset);
}
bool& HasMatchStats()
{
static auto bHasMatchStatsOffset = GetOffset("bHasMatchStats");
return Get<bool>(bHasMatchStatsOffset);
}
FAthenaMatchTeamStats* GetTeamStats()
{
static auto TeamStatsOffset = GetOffset("TeamStats");
return GetPtr<FAthenaMatchTeamStats>(TeamStatsOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.AthenaPlayerMatchReport");
return Class;
}
};

View File

@@ -1,21 +0,0 @@
#pragma once
#include "ActorComponent.h"
#include "reboot.h"
class UAthenaResurrectionComponent : public UActorComponent
{
public:
TWeakObjectPtr<AActor>& GetResurrectionLocation()
{
static auto ResurrectionLocationOffset = GetOffset("ResurrectionLocation");
return Get<TWeakObjectPtr<AActor>>(ResurrectionLocationOffset);
}
int& GetClosestSpawnMachineIndex()
{
static auto ClosestSpawnMachineIndexOffset = GetOffset("ClosestSpawnMachineIndex");
return Get<int>(ClosestSpawnMachineIndexOffset);
}
};

View File

@@ -1,48 +0,0 @@
#pragma once
#include "reboot.h"
class UAttributeSet : public UObject
{
public:
};
struct FGameplayAttribute
{
FString AttributeName;
void* Attribute; // Property
UStruct* AttributeOwner;
std::string GetAttributeName()
{
return AttributeName.ToString();
}
std::string GetAttributePropertyName()
{
if (!Attribute)
return "INVALIDATTRIBUTE";
return GetFNameOfProp(Attribute)->ToString();
}
};
struct FGameplayAttributeData
{
float& GetBaseValue()
{
static auto BaseValueOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAttributeData", "BaseValue");
return *(float*)(__int64(this) + BaseValueOffset);
}
float& GetCurrentValue()
{
static auto CurrentValueOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAttributeData", "CurrentValue");
return *(float*)(__int64(this) + CurrentValueOffset);
}
};
struct FFortGameplayAttributeData : public FGameplayAttributeData
{
};

View File

@@ -1,125 +0,0 @@
#pragma once
#include "reboot.h"
#include "GameplayStatics.h"
#include "FortLootPackage.h"
#include "FortPickup.h"
#include "BuildingGameplayActor.h"
#include "KismetSystemLibrary.h"
static inline void SpawnBGAs() // hahah not "proper", there's a function that we can hook and it gets called on each spawner whenever playlist gets set, but it's fine.
{
static auto BGAConsumableSpawnerClass = FindObject<UClass>(L"/Script/FortniteGame.BGAConsumableSpawner");
if (!BGAConsumableSpawnerClass)
return;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto AllBGAConsumableSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BGAConsumableSpawnerClass);
LOG_INFO(LogDev, "AllBGAConsumableSpawners.Num(): {}", (int)AllBGAConsumableSpawners.Num());
for (int i = 0; i < AllBGAConsumableSpawners.Num(); ++i)
{
auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i);
auto SpawnLocation = BGAConsumableSpawner->GetActorLocation();
static auto bAlignSpawnedActorsToSurfaceOffset = BGAConsumableSpawner->GetOffset("bAlignSpawnedActorsToSurface");
const bool bAlignSpawnedActorsToSurface = BGAConsumableSpawner->Get<bool>(bAlignSpawnedActorsToSurfaceOffset);
FTransform SpawnTransform{};
SpawnTransform.Translation = SpawnLocation;
SpawnTransform.Scale3D = FVector{ 1, 1, 1 };
SpawnTransform.Rotation = FQuat();
if (FBuildingGameplayActorSpawnDetails::GetStruct())
{
// todo handle?
auto MapInfo = GameState->GetMapInfo();
}
static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup");
auto& SpawnLootTierGroup = BGAConsumableSpawner->Get<FName>(SpawnLootTierGroupOffset);
auto LootDrops = PickLootDrops(SpawnLootTierGroup, GameState->GetWorldLevel());
for (int z = 0; z < LootDrops.size(); z++)
{
auto& LootDrop = LootDrops.at(z);
static auto ConsumableClassOffset = LootDrop->GetItemDefinition()->GetOffset("ConsumableClass");
auto ConsumableClassSoft = LootDrop->GetItemDefinition()->GetPtr<TSoftObjectPtr<UClass>>(ConsumableClassOffset);
static auto BlueprintGeneratedClassClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
auto StrongConsumableClass = ConsumableClassSoft->Get(BlueprintGeneratedClassClass, true);
if (!StrongConsumableClass)
{
LOG_INFO(LogDev, "Invalid consumable class!");
continue;
}
bool bDeferConstruction = true; // hm?
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnTransform, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn, bDeferConstruction));
if (ConsumableActor)
{
FTransform FinalSpawnTransform = SpawnTransform;
if (bAlignSpawnedActorsToSurface)
{
// I DONT KNOW
/* FHitResult* NewHit = Alloc<FHitResult>(FHitResult::GetStructSize());
FVector StartLocation = FinalSpawnTransform.Translation;
FVector EndLocation = StartLocation - FVector(0, 0, 1000);
bool bTraceComplex = true; // idk
FName ProfileName = UKismetStringLibrary::Conv_StringToName(L"FindGroundLocationAt");
UKismetSystemLibrary::LineTraceSingleByProfile(ConsumableActor, StartLocation, EndLocation, ProfileName, bTraceComplex,
TArray<AActor*>(), EDrawDebugTrace::None, &NewHit, true, FLinearColor(), FLinearColor(), 0);
// UKismetSystemLibrary::LineTraceSingle(ConsumableActor, StartLocation, EndLocation,
// ETraceTypeQuery::TraceTypeQuery1, bTraceComplex, TArray<AActor*>(), EDrawDebugTrace::None, true, FLinearColor(), FLinearColor(), 0, &NewHit);
bool IsBlockingHit = NewHit && NewHit->IsBlockingHit(); // Should we check ret of linetracesingle?
if (IsBlockingHit)
{
FinalSpawnTransform.Translation = NewHit->GetLocation();
}
else
{
FinalSpawnTransform.Translation = FVector(0, 0, 0);
}
*/
}
if (FinalSpawnTransform.Translation.CompareVectors(FVector(0, 0, 0)))
{
LOG_WARN(LogGame, "Invalid BGA spawn location!");
// ConsumableActor->K2_DestroyActor(); // ??
continue;
}
if (bDeferConstruction)
UGameplayStatics::FinishSpawningActor(ConsumableActor, FinalSpawnTransform);
// ConsumableActor->InitializeBuildingActor(nullptr, nullptr, true); // idk UFortKismetLibrary::SpawnBuildingGameplayActor does this
LOG_INFO(LogDev, "[{}/{}] Spawned BGA {} at {} {} {}", z, LootDrops.size(), ConsumableActor->GetName(), FinalSpawnTransform.Translation.X, FinalSpawnTransform.Translation.Y, FinalSpawnTransform.Translation.Z);
break; // ?
}
}
}
AllBGAConsumableSpawners.Free();
LOG_INFO(LogDev, "Spawned BGAS!");
}

View File

@@ -1,26 +0,0 @@
#include "BP_IslandScripting.h"
void ABP_IslandScripting_C::Initialize()
{
static auto UpdateMapOffset = GetOffset("UpdateMap", false);
if (UpdateMapOffset != -1)
{
Get<bool>(UpdateMapOffset) = true;
this->OnRep_UpdateMap();
}
/*
// This spawns the beam.
this->IsDeimosActive() = true;
this->OnRep_IsDeimosActive();
*/
}
ABP_IslandScripting_C* ABP_IslandScripting_C::GetIslandScripting()
{
auto AllIslandScriptings = UGameplayStatics::GetAllActorsOfClass(GetWorld(), StaticClass());
return AllIslandScriptings.Num() > 0 ? (ABP_IslandScripting_C*)AllIslandScriptings.at(0) : nullptr;
}

View File

@@ -1,37 +0,0 @@
#pragma once
#include "reboot.h"
#include "GameplayStatics.h"
class ABP_IslandScripting_C : public AActor // AFortAlwaysRelevantReplicatedActor
{
public:
bool& IsDeimosActive()
{
static auto IsDeimosActiveOffset = GetOffset("IsDeimosActive");
return Get<bool>(IsDeimosActiveOffset);
}
void OnRep_IsDeimosActive()
{
static auto OnRep_IsDeimosActiveFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C.OnRep_IsDeimosActive");
this->ProcessEvent(OnRep_IsDeimosActiveFn);
}
void OnRep_UpdateMap()
{
static auto OnRep_UpdateMapFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C.OnRep_UpdateMap");
this->ProcessEvent(OnRep_UpdateMapFn);
}
void Initialize();
static ABP_IslandScripting_C* GetIslandScripting();
static UClass* StaticClass()
{
/* static */ auto Class = FindObject<UClass>("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C");
return Class;
}
};

View File

@@ -1,143 +0,0 @@
#pragma once
#include "inc.h"
#include "ReversePredicate.h"
namespace AlgoImpl
{
/**
* Gets the index of the left child of node at Index.
*
* @param Index Node for which the left child index is to be returned.
* @returns Index of the left child.
*/
FORCEINLINE int32 HeapGetLeftChildIndex(int32 Index)
{
return Index * 2 + 1;
}
/**
* Checks if node located at Index is a leaf or not.
*
* @param Index Node index.
* @returns true if node is a leaf, false otherwise.
*/
FORCEINLINE bool HeapIsLeaf(int32 Index, int32 Count)
{
return HeapGetLeftChildIndex(Index) >= Count;
}
/**
* Gets the parent index for node at Index.
*
* @param Index node index.
* @returns Parent index.
*/
FORCEINLINE int32 HeapGetParentIndex(int32 Index)
{
return (Index - 1) / 2;
}
/**
* Fixes a possible violation of order property between node at Index and a child.
*
* @param Heap Pointer to the first element of a binary heap.
* @param Index Node index.
* @param Count Size of the heap.
* @param Projection The projection to apply to the elements.
* @param Predicate A binary predicate object used to specify if one element should precede another.
*/
template <typename RangeValueType, typename ProjectionType, typename PredicateType>
FORCEINLINE void HeapSiftDown(RangeValueType* Heap, int32 Index, const int32 Count, const ProjectionType& Projection, const PredicateType& Predicate)
{
while (!HeapIsLeaf(Index, Count))
{
const int32 LeftChildIndex = HeapGetLeftChildIndex(Index);
const int32 RightChildIndex = LeftChildIndex + 1;
int32 MinChildIndex = LeftChildIndex;
if (RightChildIndex < Count)
{
MinChildIndex = Predicate(Invoke(Projection, Heap[LeftChildIndex]), Invoke(Projection, Heap[RightChildIndex])) ? LeftChildIndex : RightChildIndex;
}
if (!Predicate(Invoke(Projection, Heap[MinChildIndex]), Invoke(Projection, Heap[Index])))
{
break;
}
Swap(Heap[Index], Heap[MinChildIndex]);
Index = MinChildIndex;
}
}
/**
* Fixes a possible violation of order property between node at NodeIndex and a parent.
*
* @param Heap Pointer to the first element of a binary heap.
* @param RootIndex How far to go up?
* @param NodeIndex Node index.
* @param Projection The projection to apply to the elements.
* @param Predicate A binary predicate object used to specify if one element should precede another.
*
* @return The new index of the node that was at NodeIndex
*/
template <class RangeValueType, typename ProjectionType, class PredicateType>
FORCEINLINE int32 HeapSiftUp(RangeValueType* Heap, int32 RootIndex, int32 NodeIndex, const ProjectionType& Projection, const PredicateType& Predicate)
{
while (NodeIndex > RootIndex)
{
int32 ParentIndex = HeapGetParentIndex(NodeIndex);
if (!Predicate(Invoke(Projection, Heap[NodeIndex]), Invoke(Projection, Heap[ParentIndex])))
{
break;
}
Swap(Heap[NodeIndex], Heap[ParentIndex]);
NodeIndex = ParentIndex;
}
return NodeIndex;
}
/**
* Builds an implicit min-heap from a range of elements.
* This is the internal function used by Heapify overrides.
*
* @param First pointer to the first element to heapify
* @param Num the number of items to heapify
* @param Projection The projection to apply to the elements.
* @param Predicate A binary predicate object used to specify if one element should precede another.
*/
template <typename RangeValueType, typename ProjectionType, typename PredicateType>
FORCEINLINE void HeapifyInternal(RangeValueType* First, SIZE_T Num, ProjectionType Projection, PredicateType Predicate)
{
for (int32 Index = HeapGetParentIndex(Num - 1); Index >= 0; Index--)
{
HeapSiftDown(First, Index, Num, Projection, Predicate);
}
}
/**
* Performs heap sort on the elements.
* This is the internal sorting function used by HeapSort overrides.
*
* @param First pointer to the first element to sort
* @param Num the number of elements to sort
* @param Predicate predicate class
*/
template <typename RangeValueType, typename ProjectionType, class PredicateType>
void HeapSortInternal(RangeValueType* First, SIZE_T Num, ProjectionType Projection, PredicateType Predicate)
{
TReversePredicate< PredicateType > ReversePredicateWrapper(Predicate); // Reverse the predicate to build a max-heap instead of a min-heap
HeapifyInternal(First, Num, Projection, ReversePredicateWrapper);
for (int32 Index = Num - 1; Index > 0; Index--)
{
Swap(First[0], First[Index]);
HeapSiftDown(First, 0, Index, Projection, ReversePredicateWrapper);
}
}
}

View File

@@ -1,329 +0,0 @@
#pragma once
#include "ContainerAllocationPolicies.h"
static FORCEINLINE uint32 CountLeadingZeros(uint32 Value)
{
unsigned long Log2;
if (_BitScanReverse(&Log2, Value) != 0)
{
return 31 - Log2;
}
return 32;
}
#define NumBitsPerDWORD ((int32)32)
#define NumBitsPerDWORDLogTwo ((int32)5)
class TBitArray
{
public:
TInlineAllocator<4>::ForElementType<unsigned int> Data;
int NumBits;
int MaxBits;
struct FRelativeBitReference
{
public:
FORCEINLINE explicit FRelativeBitReference(int32 BitIndex)
: DWORDIndex(BitIndex >> NumBitsPerDWORDLogTwo)
, Mask(1 << (BitIndex & (NumBitsPerDWORD -1)))
{
}
int32 DWORDIndex;
uint32 Mask;
};
public:
struct FBitReference
{
FORCEINLINE FBitReference(uint32& InData, uint32 InMask)
: Data(InData)
, Mask(InMask)
{
}
FORCEINLINE const FBitReference(const uint32& InData, const uint32 InMask)
: Data(const_cast<uint32&>(InData))
, Mask(InMask)
{
}
FORCEINLINE void SetBit(const bool Value)
{
Value ? Data |= Mask : Data &= ~Mask;
// 10011101 - Data // 10011101 - Data
// 00000010 - Mask - true | // 00000010 - Mask - false
// 10011111 - |= // 11111101 - ~
// // 10011111 - &=
}
FORCEINLINE operator bool() const
{
return (Data & Mask) != 0;
}
FORCEINLINE void operator=(const bool Value)
{
this->SetBit(Value);
}
private:
uint32& Data;
uint32 Mask;
};
public:
class FBitIterator : public FRelativeBitReference
{
private:
int32 Index;
const TBitArray& IteratedArray;
public:
FORCEINLINE const FBitIterator(const TBitArray& ToIterate, const int32 StartIndex) // Begin
: IteratedArray(ToIterate)
, Index(StartIndex)
, FRelativeBitReference(StartIndex)
{
}
FORCEINLINE const FBitIterator(const TBitArray& ToIterate) // End
: IteratedArray(ToIterate)
, Index(ToIterate.NumBits)
, FRelativeBitReference(ToIterate.NumBits)
{
}
FORCEINLINE explicit operator bool() const
{
return Index < IteratedArray.Num();
}
FORCEINLINE FBitIterator& operator++()
{
++Index;
this->Mask <<= 1;
if (!this->Mask)
{
this->Mask = 1;
++this->DWORDIndex;
}
return *this;
}
FORCEINLINE bool operator*() const
{
// Thesis: Once there are more elements in the BitArray than InlineData can hold it'll just allocate all of
// them through SecondaryElements, leaving InlineData all true
if (IteratedArray.NumBits < IteratedArray.Data.NumInlineBits())
{
return (bool)FBitReference(IteratedArray.Data.GetInlineElement(this->DWORDIndex), this->Mask);
}
else
{
return (bool)FBitReference(IteratedArray.Data.GetSecondaryElement(this->DWORDIndex), this->Mask);
}
}
FORCEINLINE bool operator==(const FBitIterator& OtherIt) const
{
return Index == OtherIt.Index;
}
FORCEINLINE bool operator!=(const FBitIterator& OtherIt) const
{
return Index </*=*/ OtherIt.Index;
}
FORCEINLINE bool operator < (const int32 Other) const
{
return Index < Other;
}
FORCEINLINE bool operator > (const int32 Other) const
{
return Index < Other;
}
FORCEINLINE int32 GetIndex() const
{
return Index;
}
};
class FSetBitIterator : public FRelativeBitReference
{
private:
const TBitArray& IteratedArray;
uint32 UnvisitedBitMask;
int32 CurrentBitIndex;
int32 BaseBitIndex;
public:
FORCEINLINE FSetBitIterator(const TBitArray& ToIterate, int32 StartIndex)
: FRelativeBitReference(StartIndex)
, IteratedArray(const_cast<TBitArray&>(ToIterate))
, UnvisitedBitMask((~0U) << (StartIndex & (NumBitsPerDWORD - 1)))
, CurrentBitIndex(StartIndex)
, BaseBitIndex(StartIndex & ~(NumBitsPerDWORD - 1))
{
if (StartIndex != IteratedArray.NumBits)
{
FindNextSetBit();
}
}
FORCEINLINE FSetBitIterator(const TBitArray& ToIterate)
: FRelativeBitReference(ToIterate.NumBits)
, IteratedArray(const_cast<TBitArray&>(ToIterate))
, UnvisitedBitMask(0)
, CurrentBitIndex(ToIterate.NumBits)
, BaseBitIndex(ToIterate.NumBits)
{
}
FORCEINLINE FSetBitIterator& operator++()
{
UnvisitedBitMask &= ~this->Mask;
FindNextSetBit();
return *this;
}
FORCEINLINE bool operator*() const
{
return true;
}
FORCEINLINE bool operator==(const FSetBitIterator& Other) const
{
return CurrentBitIndex == Other.CurrentBitIndex;
}
FORCEINLINE bool operator!=(const FSetBitIterator& Other) const
{
return CurrentBitIndex </*=*/ Other.CurrentBitIndex;
}
FORCEINLINE explicit operator bool() const
{
return CurrentBitIndex < IteratedArray.NumBits;
}
FORCEINLINE int32 GetIndex() const
{
return CurrentBitIndex;
}
private:
void FindNextSetBit()
{
//InlineData is the first 16-bytes of TBitArray
const uint32* ArrayData = (IteratedArray.Data.SecondaryData ? IteratedArray.Data.SecondaryData : (uint32*)&IteratedArray.Data.InlineData);
if (!ArrayData)
return;
const int32 ArrayNum = IteratedArray.NumBits;
const int32 LastDWORDIndex = (ArrayNum - 1) / NumBitsPerDWORD;
uint32 RemainingBitMask = ArrayData[this->DWORDIndex] & UnvisitedBitMask;
while (!RemainingBitMask)
{
++this->DWORDIndex;
BaseBitIndex += NumBitsPerDWORD;
if (this->DWORDIndex > LastDWORDIndex)
{
CurrentBitIndex = ArrayNum;
return;
}
RemainingBitMask = ArrayData[this->DWORDIndex];
UnvisitedBitMask = ~0;
}
const uint32 NewRemainingBitMask = RemainingBitMask & (RemainingBitMask - 1);
this->Mask = NewRemainingBitMask ^ RemainingBitMask;
CurrentBitIndex = BaseBitIndex + NumBitsPerDWORD - 1 - CountLeadingZeros(this->Mask);
if (CurrentBitIndex > ArrayNum)
{
CurrentBitIndex = ArrayNum;
}
}
};
public:
FORCEINLINE FBitIterator Iterator(int32 StartIndex)
{
return FBitIterator(*this, StartIndex);
}
FORCEINLINE FSetBitIterator SetBitIterator(int32 StartIndex)
{
return FSetBitIterator(*this, StartIndex);
}
FORCEINLINE FBitIterator begin()
{
return FBitIterator(*this, 0);
}
FORCEINLINE const FBitIterator begin() const
{
return FBitIterator(*this, 0);
}
FORCEINLINE FBitIterator end()
{
return FBitIterator(*this);
}
FORCEINLINE const FBitIterator end() const
{
return FBitIterator(*this);
}
FORCEINLINE FSetBitIterator SetBitsItBegin()
{
return FSetBitIterator(*this, 0);
}
FORCEINLINE const FSetBitIterator SetBitsItBegin() const
{
return FSetBitIterator(*this, 0);
}
FORCEINLINE const FSetBitIterator SetBitsItEnd()
{
return FSetBitIterator(*this);
}
FORCEINLINE const FSetBitIterator SetBitsItEnd() const
{
return FSetBitIterator(*this);
}
FORCEINLINE int32 Num() const
{
return NumBits;
}
FORCEINLINE int32 Max() const
{
return MaxBits;
}
FORCEINLINE bool IsSet(int32 Index) const
{
return *FBitIterator(*this, Index);
}
FORCEINLINE void Set(const int32 Index, const bool Value, bool bIsSettingAllZero = false)
{
const int32 DWORDIndex = (Index >> ((int32)5));
const int32 Mask = (1 << (Index & (((int32)32) - 1)));
if (!bIsSettingAllZero)
NumBits = Index >= NumBits ? Index < MaxBits ? Index + 1 : NumBits : NumBits;
FBitReference(Data[DWORDIndex], Mask).SetBit(Value);
}
FORCEINLINE void ZeroAll()
{
for (int i = 0; i < MaxBits; ++i)
{
Set(i, false, true);
}
}
};

View File

@@ -1,120 +0,0 @@
#include "BuildingActor.h"
#include "FortWeapon.h"
#include "BuildingSMActor.h"
#include "FortPlayerControllerAthena.h"
#include "FortPawn.h"
#include "FortWeaponMeleeItemDefinition.h"
#include "CurveTable.h"
#include "DataTable.h"
#include "FortResourceItemDefinition.h"
#include "FortKismetLibrary.h"
#include "DataTableFunctionLibrary.h"
void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext)
{
// LOG_INFO(LogDev, "Befor3e");
auto BuildingSMActor = Cast<ABuildingSMActor>(BuildingActor);
auto PlayerController = Cast<AFortPlayerControllerAthena>(InstigatedBy);
// auto Pawn = PlayerController ? PlayerController->GetMyFortPawn() : nullptr;
auto Weapon = Cast<AFortWeapon>(DamageCauser);
if (!BuildingSMActor)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
if (BuildingSMActor->IsDestroyed())
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
/*
static auto LastDamageAmountOffset = BuildingSMActor->GetOffset("LastDamageAmount");
static auto LastDamageHitOffset = BuildingSMActor->GetOffset("LastDamageHit", false) != -1 ? BuildingSMActor->GetOffset("LastDamageHit") : BuildingSMActor->GetOffset("LastDamageHitImpulseDir"); // idc
const float PreviousLastDamageAmount = BuildingSMActor->Get<float>(LastDamageAmountOffset);
const float PreviousLastDamageHit = BuildingSMActor->Get<float>(LastDamageHitOffset);
const float CurrentBuildingHealth = BuildingActor->GetHealth();
BuildingSMActor->Get<float>(LastDamageAmountOffset) = Damage;
BuildingSMActor->Get<float>(LastDamageHitOffset) = CurrentBuildingHealth;
*/
if (!PlayerController || !Weapon)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
// if (!Pawn)
// return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
auto WeaponData = Cast<UFortWeaponMeleeItemDefinition>(Weapon->GetWeaponData());
if (!WeaponData)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
UFortResourceItemDefinition* ItemDef = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingSMActor->GetResourceType());
if (!ItemDef)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
static auto BuildingResourceAmountOverrideOffset = BuildingSMActor->GetOffset("BuildingResourceAmountOverride");
auto& BuildingResourceAmountOverride = BuildingSMActor->Get<FCurveTableRowHandle>(BuildingResourceAmountOverrideOffset);
int ResourceCount = 0;
if (BuildingResourceAmountOverride.RowName.IsValid())
{
// auto AssetManager = Cast<UFortAssetManager>(GEngine->AssetManager);
// auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameStateAthena);
UCurveTable* CurveTable = nullptr; // GameState->CurrentPlaylistInfo.BasePlaylist ? GameState->CurrentPlaylistInfo.BasePlaylist->ResourceRates.Get() : nullptr;
// LOG_INFO(LogDev, "Before1");
if (!CurveTable)
CurveTable = FindObject<UCurveTable>(L"/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates");
{
// auto curveMap = ((UDataTable*)CurveTable)->GetRowMap();
// LOG_INFO(LogDev, "Before {}", __int64(CurveTable));
float Out = UDataTableFunctionLibrary::EvaluateCurveTableRow(CurveTable, BuildingResourceAmountOverride.RowName, 0.f);
// LOG_INFO(LogDev, "Out: {}", Out);
const float DamageThatWillAffect = /* PreviousLastDamageHit > 0 && Damage > PreviousLastDamageHit ? PreviousLastDamageHit : */ Damage;
float skid = Out / (BuildingActor->GetMaxHealth() / DamageThatWillAffect);
ResourceCount = round(skid);
}
}
if (ResourceCount <= 0)
{
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
}
bool bIsWeakspot = Damage == 100.0f;
PlayerController->ClientReportDamagedResourceBuilding(BuildingSMActor, BuildingSMActor->GetResourceType(), ResourceCount, false, bIsWeakspot);
bool bShouldUpdate = false;
WorldInventory->AddItem(ItemDef, &bShouldUpdate, ResourceCount);
if (bShouldUpdate)
WorldInventory->Update();
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
}
UClass* ABuildingActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingActor");
return Class;
}

View File

@@ -1,99 +0,0 @@
#pragma once
#include "Actor.h"
#include "reboot.h" // we want to prevent this but im to lazy to make cpp file
#include "PlayerController.h"
#include "GameplayTagContainer.h"
class ABuildingActor : public AActor
{
public:
void InitializeBuildingActor(UObject* Controller, ABuildingActor* BuildingOwner, bool bUsePlayerBuildAnimations, UObject* ReplacedBuilding = nullptr)
{
struct {
UObject* BuildingOwner; // ABuildingActor
UObject* SpawningController;
bool bUsePlayerBuildAnimations; // I think this is not on some versions
UObject* ReplacedBuilding; // this also not on like below 18.00
} IBAParams{ BuildingOwner, Controller, bUsePlayerBuildAnimations, ReplacedBuilding };
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.InitializeKismetSpawnedBuildingActor");
this->ProcessEvent(fn, &IBAParams);
}
bool IsDestroyed()
{
static auto bDestroyedOffset = GetOffset("bDestroyed");
static auto bDestroyedFieldMask = GetFieldMask(GetProperty("bDestroyed"));
return ReadBitfieldValue(bDestroyedOffset, bDestroyedFieldMask);
}
void SilentDie()
{
static auto SilentDieFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.SilentDie");
bool bPropagateSilentDeath = false; // idfk
this->ProcessEvent(SilentDieFn, &bPropagateSilentDeath);
}
float GetMaxHealth()
{
float MaxHealth = 0;
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.GetMaxHealth");
this->ProcessEvent(fn, &MaxHealth);
return MaxHealth;
}
float GetHealthPercent() // aka GetHealth() / GetMaxHealth()
{
float HealthPercent = 0;
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.GetHealthPercent");
this->ProcessEvent(fn, &HealthPercent);
return HealthPercent;
}
float GetHealth()
{
float Health = 0;
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.GetHealth");
this->ProcessEvent(fn, &Health);
return Health;
}
void SetTeam(unsigned char InTeam)
{
static auto fn = nullptr; // FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.SetTeam");
if (!fn)
{
static auto TeamOffset = GetOffset("Team");
Get<uint8_t>(TeamOffset) = InTeam;
static auto TeamIndexOffset = GetOffset("TeamIndex", false);
if (TeamIndexOffset != -1)
Get<uint8_t>(TeamIndexOffset) = InTeam;
}
else
{
this->ProcessEvent(fn, &InTeam);
}
}
bool IsPlayerBuildable()
{
static auto bIsPlayerBuildableOffset = GetOffset("bIsPlayerBuildable");
static auto bIsPlayerBuildableFieldMask = GetFieldMask(GetProperty("bIsPlayerBuildable"));
return ReadBitfieldValue(bIsPlayerBuildableOffset, bIsPlayerBuildableFieldMask);
}
static inline void (*OnDamageServerOriginal)(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext);
static void OnDamageServerHook(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext);
static UClass* StaticClass();
};

View File

@@ -1,49 +0,0 @@
#include "BuildingContainer.h"
#include "FortPickup.h"
#include "FortLootPackage.h"
#include "FortGameModeAthena.h"
#include "gui.h"
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
{
if (!Pawn)
return false;
this->ForceNetUpdate();
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorForwardVector() * this->GetLootSpawnLocation_Athena().X + this->GetActorRightVector() * this->GetLootSpawnLocation_Athena().Y + this->GetActorUpVector() * this->GetLootSpawnLocation_Athena().Z;
auto RedirectedLootTier = GameMode->RedirectLootTier(GetSearchLootTierGroup());
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto LootDrops = PickLootDrops(RedirectedLootTier, GameState->GetWorldLevel(), -1, bDebugPrintLooting);
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
for (auto& lootDrop : LootDrops)
{
PickupCreateData CreateData;
CreateData.bToss = true;
// CreateData.PawnOwner = Pawn;
CreateData.ItemEntry = lootDrop.ItemEntry;
CreateData.SpawnLocation = LocationToSpawnLoot;
CreateData.SourceType = EFortPickupSourceTypeFlag::GetContainerValue();
CreateData.bRandomRotation = true;
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
}
if (!this->IsDestroyed())
{
this->ForceNetUpdate();
// a buncha other stuff
}
return true;
}

View File

@@ -1,73 +0,0 @@
#pragma once
#include "BuildingSMActor.h"
#include "FortPawn.h"
class ABuildingContainer : public ABuildingSMActor
{
public:
bool ShouldDestroyOnSearch()
{
static auto bDestroyContainerOnSearchOffset = GetOffset("bDestroyContainerOnSearch");
static auto bDestroyContainerOnSearchFieldMask = GetFieldMask(GetProperty("bDestroyContainerOnSearch"));
return this->ReadBitfieldValue(bDestroyContainerOnSearchOffset, bDestroyContainerOnSearchFieldMask);
}
FName& GetSearchLootTierGroup()
{
static auto SearchLootTierGroupOffset = this->GetOffset("SearchLootTierGroup");
return Get<FName>(SearchLootTierGroupOffset);
}
bool IsAlreadySearched()
{
static auto bAlreadySearchedOffset = this->GetOffset("bAlreadySearched");
static auto bAlreadySearchedFieldMask = GetFieldMask(this->GetProperty("bAlreadySearched"));
return this->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask);
}
FVector& GetLootSpawnLocation_Athena()
{
static auto LootSpawnLocation_AthenaOffset = this->GetOffset("LootSpawnLocation_Athena");
return this->Get<FVector>(LootSpawnLocation_AthenaOffset);
}
void SetAlreadySearched(bool bNewValue, bool bOnRep = true)
{
static auto bAlreadySearchedOffset = this->GetOffset("bAlreadySearched");
static auto bAlreadySearchedFieldMask = GetFieldMask(this->GetProperty("bAlreadySearched"));
this->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, bNewValue);
if (bOnRep)
{
static auto OnRep_bAlreadySearchedFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched");
this->ProcessEvent(OnRep_bAlreadySearchedFn);
}
}
FVector& GetLootSpawnLocation()
{
static auto LootSpawnLocationOffset = GetOffset("LootSpawnLocation");
return Get<FVector>(LootSpawnLocationOffset);
}
float& GetLootNoiseRange()
{
static auto LootNoiseRangeOffset = GetOffset("LootNoiseRange");
return Get<float>(LootNoiseRangeOffset);
}
void BounceContainer()
{
static auto BounceContainerFn = FindObject<UFunction>("/Script/FortniteGame.BuildingContainer.BounceContainer");
this->ProcessEvent(BounceContainerFn);
}
bool SpawnLoot(AFortPawn* Pawn);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.BuildingContainer");
return Class;
}
};

View File

@@ -1,30 +0,0 @@
#include "BuildingFoundation.h"
#include "FortGameModeAthena.h"
void ABuildingFoundation::SetDynamicFoundationTransformHook(UObject* Context, FFrame& Stack, void* Ret)
{
FTransform NewTransform;
Stack.StepCompiledIn(&NewTransform);
auto BuildingFoundation = (ABuildingFoundation*)Context;
LOG_INFO(LogDev, "Bruh: {}", BuildingFoundation->GetName());
SetFoundationTransform(BuildingFoundation, NewTransform);
return SetDynamicFoundationTransformOriginal(Context, Stack, Ret);
}
void ABuildingFoundation::SetDynamicFoundationEnabledHook(UObject* Context, FFrame& Stack, void* Ret)
{
bool bEnabled;
Stack.StepCompiledIn(&bEnabled);
// LOG_INFO(LogDev, "{} TELL MILXNOR IF THIS PRINTS: {}", Context->GetFullName(), bEnabled);
auto BuildingFoundation = (ABuildingFoundation*)Context;
ShowFoundation(BuildingFoundation, bEnabled);
return SetDynamicFoundationEnabledOriginal(Context, Stack, Ret);
}

View File

@@ -1,40 +0,0 @@
#pragma once
#include "BuildingSMActor.h"
#include "Stack.h"
/* enum class EDynamicFoundationType : uint8
{
Static = 0,
StartEnabled_Stationary = 1,
StartEnabled_Dynamic = 2,
StartDisabled = 3,
EDynamicFoundationType_MAX = 4,
};
enum class EDynamicFoundationEnabledState : uint8_t
{
Unknown = 0,
Enabled = 1,
Disabled = 2,
EDynamicFoundationEnabledState_MAX = 3
};
enum class EDynamicFoundationType : uint8_t
{
Static = 0,
StartEnabled_Stationary = 1,
StartEnabled_Dynamic = 2,
StartDisabled = 3,
EDynamicFoundationType_MAX = 4
}; */
class ABuildingFoundation : public ABuildingSMActor
{
public:
static inline void (*SetDynamicFoundationEnabledOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static inline void (*SetDynamicFoundationTransformOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static void SetDynamicFoundationTransformHook(UObject* Context, FFrame& Stack, void* Ret);
static void SetDynamicFoundationEnabledHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -1,8 +0,0 @@
#pragma once
#include "BuildingActor.h"
class ABuildingGameplayActor : public ABuildingActor
{
public:
};

View File

@@ -1,139 +0,0 @@
#include "BuildingGameplayActorSpawnMachine.h"
#include "FortPlayerControllerAthena.h"
#include "GameplayStatics.h"
#include "AthenaResurrectionComponent.h"
#include "FortGameStateAthena.h"
#include "FortGameModeAthena.h"
void ABuildingGameplayActorSpawnMachine::FinishResurrection(int SquadId)
{
static void (*FinishResurrectionOriginal)(ABuildingGameplayActorSpawnMachine* SpawnMachine, int SquadId) = decltype(FinishResurrectionOriginal)(Addresses::FinishResurrection);
if (FinishResurrectionOriginal)
{
FinishResurrectionOriginal(this, SquadId);
}
else
{
}
}
void ABuildingGameplayActorSpawnMachine::RebootingDelegateHook(ABuildingGameplayActorSpawnMachine* SpawnMachine)
{
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
LOG_INFO(LogDev, "RebootingDelegateHook!");
if (!SpawnMachine->GetResurrectLocation())
{
LOG_WARN(LogRebooting, "Reboot van did not have a resurrection location!");
return;
}
LOG_INFO(LogDev, "PlayerIdsForResurrection.Num(): {}", SpawnMachine->GetPlayerIdsForResurrection().Num());
if (SpawnMachine->GetPlayerIdsForResurrection().Num() <= 0)
return;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
AFortPlayerControllerAthena* PlayerController = nullptr;
if (auto TeamArrayContainer = GameState->GetTeamsArrayContainer())
{
auto& SquadArray = TeamArrayContainer->SquadsArray.at(SpawnMachine->GetSquadId());
for (int i = 0; i < SquadArray.Num(); ++i)
{
auto StrongPlayerState = SquadArray.at(i).Get();
if (!StrongPlayerState)
continue;
PlayerController = Cast<AFortPlayerControllerAthena>(StrongPlayerState->GetOwner());
if (!PlayerController)
continue;
if (PlayerController->InternalIndex == SpawnMachine->GetInstigatorPC().ObjectIndex)
continue;
break;
}
}
if (!PlayerController)
return;
auto PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerState)
return;
auto ResurrectionComponent = PlayerController->GetResurrectionComponent();
if (!ResurrectionComponent)
return;
static auto FortPlayerStartClass = FindObject<UClass>(L"/Script/FortniteGame.FortPlayerStart");
if (true) // i dont think we actually need this
{
ResurrectionComponent->GetResurrectionLocation().ObjectIndex = SpawnMachine->GetResurrectLocation()->InternalIndex;
ResurrectionComponent->GetResurrectionLocation().ObjectSerialNumber = GetItemByIndex(SpawnMachine->GetResurrectLocation()->InternalIndex)->SerialNumber;
}
auto StrongResurrectionLocation = ResurrectionComponent->GetResurrectionLocation().Get();
LOG_INFO(LogDev, "StrongResurrectionLocation: {} IsRespawnDataAvailable: {}", __int64(StrongResurrectionLocation), PlayerState->GetRespawnData()->IsRespawnDataAvailable());
if (!StrongResurrectionLocation)
return;
PlayerState->GetRespawnData()->IsRespawnDataAvailable() = false;
PlayerController->SetPlayerIsWaiting(true);
// PlayerController->ServerRestartPlayer();
bool bEnterSkydiving = false; // TODO get from like curve table iirc idk or the variable
PlayerController->RespawnPlayerAfterDeath(bEnterSkydiving);
AFortPlayerPawn* NewPawn = Cast<AFortPlayerPawn>(PlayerController->GetMyFortPawn());
LOG_INFO(LogDev, "NewPawn: {}", __int64(NewPawn));
if (!NewPawn) // Failed to restart player
{
LOG_INFO(LogRebooting, "Failed to restart the player!");
return;
}
PlayerController->ClientClearDeathNotification();
NewPawn->SetHealth(100);
NewPawn->SetMaxHealth(100);
static auto RebootCounterOffset = PlayerState->GetOffset("RebootCounter");
PlayerState->Get<int>(RebootCounterOffset)++;
static auto OnRep_RebootCounterFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.OnRep_RebootCounter");
PlayerState->ProcessEvent(OnRep_RebootCounterFn);
auto OnPlayerPawnResurrectedFn = SpawnMachine->FindFunction("OnPlayerPawnResurrected");
SpawnMachine->ProcessEvent(OnPlayerPawnResurrectedFn, &NewPawn);
static void (*AddToAlivePlayersOriginal)(AFortGameModeAthena* GameMode, AFortPlayerControllerAthena* Player) = decltype(AddToAlivePlayersOriginal)(Addresses::AddToAlivePlayers);
if (AddToAlivePlayersOriginal)
{
AddToAlivePlayersOriginal(GameMode, PlayerController);
}
bool IsFinalPlayerToBeRebooted = true;
if (IsFinalPlayerToBeRebooted)
{
SpawnMachine->FinishResurrection(PlayerState->GetSquadId());
}
}

View File

@@ -1,49 +0,0 @@
#pragma once
#include "BuildingGameplayActor.h"
#include "OnlineReplStructs.h"
#include "WeakObjectPtr.h"
class ABuildingGameplayActorSpawnMachine : public ABuildingGameplayActor
{
public:
TArray<FUniqueNetIdRepl>& GetPlayerIdsForResurrection()
{
static auto PlayerIdsForResurrectionOffset = GetOffset("PlayerIdsForResurrection");
return Get<TArray<FUniqueNetIdRepl>>(PlayerIdsForResurrectionOffset);
}
AActor*& GetResurrectLocation() // actually AFortPlayerStart
{
static auto ResurrectLocationOffset = GetOffset("ResurrectLocation");
return Get<AActor*>(ResurrectLocationOffset);
}
uint8& GetActiveTeam()
{
static auto ActiveTeamOffset = GetOffset("ActiveTeam");
return Get<uint8>(ActiveTeamOffset);
}
uint8& GetSquadId()
{
static auto SquadIdOffset = GetOffset("SquadId");
return Get<uint8>(SquadIdOffset);
}
TWeakObjectPtr<class AFortPlayerControllerAthena> GetInstigatorPC()
{
static auto InstigatorPCOffset = GetOffset("InstigatorPC");
return Get<TWeakObjectPtr<class AFortPlayerControllerAthena>>(InstigatorPCOffset);
}
void FinishResurrection(int SquadId);
static void RebootingDelegateHook(ABuildingGameplayActorSpawnMachine* SpawnMachine);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingGameplayActorSpawnMachine");
return Class;
}
};

View File

@@ -1,14 +0,0 @@
#pragma once
#include "BuildingGameplayActor.h"
class ABuildingItemWeaponUpgradeActor : public ABuildingGameplayActor // ABuildingItemCollectorActor
{
public:
static class UClass* StaticClass()
{
static UClass* Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingItemWeaponUpgradeActor");
return Class;
}
};

View File

@@ -1,8 +0,0 @@
#pragma once
#include "BuildingActor.h"
class ABuildingRift : public ABuildingActor
{
public:
};

View File

@@ -1,7 +0,0 @@
#include "BuildingSMActor.h"
UClass* ABuildingSMActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingSMActor");
return Class;
}

View File

@@ -1,64 +0,0 @@
#pragma once
#include "BuildingActor.h"
#include "PlayerState.h"
enum class EFortResourceType : uint8_t
{
Wood = 0,
Stone = 1,
Metal = 2,
Permanite = 3,
None = 4,
EFortResourceType_MAX = 5
};
class ABuildingSMActor : public ABuildingActor
{
public:
bool IsPlayerPlaced()
{
static auto bPlayerPlacedOffset = GetOffset("bPlayerPlaced");
static auto bPlayerPlacedFieldMask = GetFieldMask(this->GetProperty("bPlayerPlaced"));
return ReadBitfieldValue(bPlayerPlacedOffset, bPlayerPlacedFieldMask);
}
void SetPlayerPlaced(bool NewValue)
{
static auto bPlayerPlacedOffset = GetOffset("bPlayerPlaced");
static auto bPlayerPlacedFieldMask = GetFieldMask(this->GetProperty("bPlayerPlaced"));
this->SetBitfieldValue(bPlayerPlacedOffset, bPlayerPlacedFieldMask, NewValue);
}
APlayerState*& GetEditingPlayer()
{
static auto EditingPlayerOffset = GetOffset("EditingPlayer");
return Get<APlayerState*>(EditingPlayerOffset);
}
int& GetCurrentBuildingLevel()
{
static auto CurrentBuildingLevelOffset = GetOffset("CurrentBuildingLevel");
return Get<int>(CurrentBuildingLevelOffset);
}
EFortResourceType& GetResourceType()
{
static auto ResourceTypeOffset = GetOffset("ResourceType");
return Get<EFortResourceType>(ResourceTypeOffset);
}
void SetEditingPlayer(APlayerState* NewEditingPlayer) // actually AFortPlayerStateZone
{
if (// AActor::HasAuthority() &&
(!GetEditingPlayer() || !NewEditingPlayer)
)
{
SetNetDormancy((ENetDormancy)(2 - (NewEditingPlayer != 0)));
// they do something here
GetEditingPlayer() = NewEditingPlayer;
}
}
static UClass* StaticClass();
};

View File

@@ -1,17 +0,0 @@
#include "BuildingStructuralSupportSystem.h"
#include "reboot.h"
bool UBuildingStructuralSupportSystem::IsWorldLocValid(const FVector& WorldLoc)
{
static auto IsWorldLocValidFn = FindObject<UFunction>("/Script/FortniteGame.BuildingStructuralSupportSystem.IsWorldLocValid");
if (!IsWorldLocValidFn)
return true;
struct { FVector WorldLoc; bool Ret; } Params{ WorldLoc };
this->ProcessEvent(IsWorldLocValidFn, &Params);
return Params.Ret;
}

View File

@@ -1,10 +0,0 @@
#pragma once
#include "Object.h"
#include "Vector.h"
class UBuildingStructuralSupportSystem : public UObject
{
public:
bool IsWorldLocValid(const FVector& WorldLoc);
};

View File

@@ -1,4 +0,0 @@
#include "BuildingTrap.h"
#include "GameplayStatics.h"
#include "FortPlayerStateAthena.h"

View File

@@ -1,9 +0,0 @@
#pragma once
#include "BuildingSMActor.h"
class ABuildingTrap : public ABuildingSMActor
{
public:
};

View File

@@ -1,15 +0,0 @@
#include "BuildingWeapons.h"
#include "reboot.h"
void AFortWeap_EditingTool::OnRep_EditActor()
{
static auto OnRep_EditActorFn = FindObject<UFunction>("/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor");
this->ProcessEvent(OnRep_EditActorFn);
}
UClass* AFortWeap_EditingTool::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortWeap_EditingTool");
return Class;
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include "BuildingSMActor.h"
#include "FortWeapon.h"
class AFortWeap_BuildingToolBase : public AFortWeapon
{
};
class AFortWeap_BuildingTool : public AFortWeap_BuildingToolBase
{
};
class AFortWeap_EditingTool : public AFortWeap_BuildingToolBase
{
public:
ABuildingSMActor*& GetEditActor()
{
static auto EditActorOffset = GetOffset("EditActor");
return Get<ABuildingSMActor*>(EditActorOffset);
}
void OnRep_EditActor();
static UClass* StaticClass();
};

View File

@@ -1,27 +0,0 @@
#pragma once
#include "Object.h"
class UChannel : public UObject
{
public:
void StartBecomingDormant()
{
void (*StartBecomingDormantOriginal)(UChannel* Channel) = decltype(StartBecomingDormantOriginal)(this->VFTable[0x298 / 8]);
StartBecomingDormantOriginal(this);
}
bool IsPendingDormancy()
{
static auto BitfieldOffset = GetOffset("Connection") + 8;
return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Seventh;
}
bool IsDormant()
{
static auto BitfieldOffset = GetOffset("Connection") + 8;
return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Third;
}
int32 IsNetReady(bool Saturate);
};

View File

@@ -1,21 +0,0 @@
#include "CheatManager.h"
#include "reboot.h"
void UCheatManager::Teleport()
{
static auto TeleportFn = FindObject<UFunction>(L"/Script/Engine.CheatManager.Teleport");
this->ProcessEvent(TeleportFn);
}
void UCheatManager::DestroyTarget()
{
static auto DestroyTargetFn = FindObject<UFunction>("/Script/Engine.CheatManager.DestroyTarget");
this->ProcessEvent(DestroyTargetFn);
}
UClass* UCheatManager::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.CheatManager");
return Class;
}

View File

@@ -1,12 +0,0 @@
#pragma once
#include "Object.h"
class UCheatManager : public UObject
{
public:
void Teleport();
void DestroyTarget();
static UClass* StaticClass();
};

View File

@@ -1,53 +0,0 @@
#pragma once
#include "Class.h"
#include "reboot.h"
UObject* UClass::CreateDefaultObject()
{
static std::unordered_map<std::string, UObject*> defaultAbilities; // normal class name, default ability.
static int LastNum1 = 151;
if (LastNum1 != Globals::AmountOfListens)
{
LastNum1 = Globals::AmountOfListens;
defaultAbilities.clear();
}
auto name = this->GetFullName();
if (name.contains("Default__"))
return this;
auto defaultafqaf = defaultAbilities.find(name);
UObject* DefaultObject = nullptr;
if (defaultafqaf != defaultAbilities.end())
{
DefaultObject = defaultafqaf->second;
}
else
{
// skunked class to default
auto ending = name.substr(name.find_last_of(".") + 1);
auto path = name.substr(0, name.find_last_of(".") + 1);
path = path.substr(path.find_first_of(" ") + 1);
auto DefaultAbilityName = std::format("{0}Default__{1}", path, ending);
// std::cout << "DefaultAbilityName: " << DefaultAbilityName << '\n';
DefaultObject = FindObject(DefaultAbilityName);
defaultAbilities.emplace(name, DefaultObject);
}
return DefaultObject;
}
int UStruct::GetPropertiesSize()
{
return *(int*)(__int64(this) + Offsets::PropertiesSize);
}

View File

@@ -1,85 +0,0 @@
#pragma once
#include "Object.h"
#include "addresses.h"
#include "UnrealString.h"
#include "Map.h"
struct UField : UObject
{
UField* Next;
// void* pad; void* pad2;
};
struct UFieldPadding : UObject
{
UField* Next;
void* pad; void* pad2;
};
template <typename PropertyType = void>
static inline PropertyType* GetNext(void* Field)
{
return Fortnite_Version >= 12.10 ? *(PropertyType**)(__int64(Field) + 0x20) : ((UField*)Field)->Next;
}
static inline FName* GetFNameOfProp(void* Property)
{
FName* NamePrivate = nullptr;
if (Fortnite_Version >= 12.10)
NamePrivate = (FName*)(__int64(Property) + 0x28);
else
NamePrivate = &((UField*)Property)->NamePrivate;
return NamePrivate;
}
class UStruct : public UField
{
public:
int GetPropertiesSize();
UStruct* GetSuperStruct() { return *(UStruct**)(__int64(this) + Offsets::SuperStruct); } // idk if this is in UStruct
TArray<uint8_t> GetScript() { return *(TArray<uint8_t>*)(__int64(this) + Offsets::Script); }
};
class UClass : public UStruct
{
public:
UObject* CreateDefaultObject();
};
class UFunction : public UStruct
{
public:
void*& GetFunc() { return *(void**)(__int64(this) + Offsets::Func); }
};
class UEnum : public UField
{
public:
int64 GetValue(const std::string& EnumMemberName)
{
auto Names = (TArray<TPair<FName, int64>>*)(__int64(this) + sizeof(UField) + sizeof(FString));
for (int i = 0; i < Names->Num(); ++i)
{
auto& Pair = Names->At(i);
auto& Name = Pair.Key();
auto Value = Pair.Value();
if (Name.ComparisonIndex.Value)
{
auto nameStr = Name.ToString();
if (nameStr.contains(EnumMemberName))
return Value;
}
}
return -1;
}
};

View File

@@ -1,117 +0,0 @@
#pragma once
#include "NumericLimits.h"
template <int NumElements>
class TInlineAllocator
{
private:
template <int Size, int Alignment>
struct alignas(Alignment) TAlignedBytes
{
unsigned char Pad[Size];
};
template <typename ElementType>
struct TTypeCompatibleBytes : public TAlignedBytes<sizeof(ElementType), alignof(ElementType)>
{
};
public:
template <typename ElementType>
class ForElementType
{
friend class TBitArray;
private:
TTypeCompatibleBytes<ElementType> InlineData[NumElements];
ElementType* SecondaryData;
public:
FORCEINLINE int32 NumInlineBytes() const
{
return sizeof(ElementType) * NumElements;
}
FORCEINLINE int32 NumInlineBits() const
{
return NumInlineBytes() * 8;
}
FORCEINLINE ElementType& operator[](int32 Index)
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE const ElementType& operator[](int32 Index) const
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE void operator=(void* InElements)
{
SecondaryData = InElements;
}
FORCEINLINE ElementType& GetInlineElement(int32 Index)
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE const ElementType& GetInlineElement(int32 Index) const
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE ElementType& GetSecondaryElement(int32 Index)
{
return SecondaryData[Index];
}
FORCEINLINE const ElementType& GetSecondaryElement(int32 Index) const
{
return SecondaryData[Index];
}
ElementType* GetInlineElements() const
{
return (ElementType*)InlineData;
}
FORCEINLINE ElementType* GetAllocation() const
{
return IfAThenAElseB<ElementType>(SecondaryData, GetInlineElements());
}
};
};
FORCEINLINE /*FMEMORY_INLINE_FUNCTION_DECORATOR*/ size_t /*FMemory::*/QuantizeSize(SIZE_T Count, uint32 Alignment)
{
return Count;
/*
if (!FMEMORY_INLINE_GMalloc)
{
return Count;
}
return FMEMORY_INLINE_GMalloc->QuantizeSize(Count, Alignment); */
}
enum
{
DEFAULT_ALIGNMENT = 0
};
template <typename SizeType>
FORCEINLINE SizeType DefaultCalculateSlackReserve(SizeType NumElements, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment = DEFAULT_ALIGNMENT)
{
SizeType Retval = NumElements;
// checkSlow(NumElements > 0);
if (bAllowQuantize)
{
auto Count = SIZE_T(Retval) * SIZE_T(BytesPerElement);
Retval = (SizeType)(QuantizeSize(Count, Alignment) / BytesPerElement);
// NumElements and MaxElements are stored in 32 bit signed integers so we must be careful not to overflow here.
if (NumElements > Retval)
{
Retval = TNumericLimits<SizeType>::Max();
}
}
return Retval;
}

View File

@@ -1,17 +0,0 @@
#include "Controller.h"
#include "reboot.h"
AActor* AController::GetViewTarget()
{
static auto GetViewTargetFn = FindObject<UFunction>("/Script/Engine.Controller.GetViewTarget");
AActor* ViewTarget = nullptr;
this->ProcessEvent(GetViewTargetFn, &ViewTarget);
return ViewTarget;
}
void AController::Possess(class APawn* Pawn)
{
auto PossessFn = FindFunction("Possess");
this->ProcessEvent(PossessFn, &Pawn);
}

View File

@@ -1,28 +0,0 @@
#pragma once
#include "Actor.h"
class AController : public AActor
{
public:
AActor* GetViewTarget();
void Possess(class APawn* Pawn);
FName& GetStateName()
{
static auto StateNameOffset = GetOffset("StateName");
return Get<FName>(StateNameOffset);
}
class APawn*& GetPawn()
{
static auto PawnOffset = this->GetOffset("Pawn");
return this->Get<class APawn*>(PawnOffset);
}
class APlayerState*& GetPlayerState()
{
static auto PlayerStateOffset = this->GetOffset("PlayerState");
return this->Get<class APlayerState*>(PlayerStateOffset);
}
};

View File

@@ -1,94 +0,0 @@
#pragma once
#include "Object.h"
#include "NameTypes.h"
#include "reboot.h"
#include "DataTable.h"
enum class ECurveTableMode : unsigned char
{
Empty,
SimpleCurves,
RichCurves
};
struct FSimpleCurveKey
{
float Time; // 0x0000(0x0004) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
float Value; // 0x0004(0x0004) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
struct FIndexedCurve
{
};
struct FRealCurve : public FIndexedCurve
{
};
struct FSimpleCurve : public FRealCurve
{
TArray<FSimpleCurveKey>& GetKeys()
{
static auto KeysOffset = FindOffsetStruct("/Script/Engine.SimpleCurve", "Keys");
return *(TArray<FSimpleCurveKey>*)(__int64(this) + KeysOffset);
}
};
class UCurveTable : public UObject
{
public:
static int GetCurveTableSize()
{
static auto CurveTableClass = FindObject<UClass>("/Script/Engine.CurveTable");
return CurveTableClass->GetPropertiesSize();
}
ECurveTableMode GetCurveTableMode() const
{
static auto CurveTableModeOffset = GetCurveTableSize() - 8;
return *(ECurveTableMode*)(__int64(this) + CurveTableModeOffset);
}
void* GetKey(const FName& RowName, int Index)
{
auto CurveTableMode = GetCurveTableMode();
// LOG_INFO(LogDev, "RowName {} CurveTableMode {} Size {}", RowName.ComparisonIndex.Value ? RowName.ToString() : "InvalidComparision", (int)CurveTableMode, GetCurveTableSize());
if (CurveTableMode == ECurveTableMode::SimpleCurves)
{
auto& RowMap = ((UDataTable*)this)->GetRowMap<FSimpleCurve>(); // its the same offset so
auto Curve = RowMap.Find(RowName);
auto& Keys = Curve->GetKeys();
return Keys.Num() > Index ? &Curve->GetKeys().at(Index) : nullptr;
}
else if (CurveTableMode == ECurveTableMode::RichCurves)
{
LOG_INFO(LogDev, "RICHCURVE UNIMPLEMENTED!");
}
return nullptr;
}
float GetValueOfKey(void* Key)
{
if (!Key)
return 0.f;
auto CurveTableMode = GetCurveTableMode();
if (CurveTableMode == ECurveTableMode::SimpleCurves) return ((FSimpleCurveKey*)Key)->Value;
else if (CurveTableMode == ECurveTableMode::RichCurves) return 0.f;
return 0.f;
}
};
struct FCurveTableRowHandle
{
UCurveTable* CurveTable;
FName RowName;
};

View File

@@ -1,16 +0,0 @@
#include "Channel.h"
#include "NetConnection.h"
int32 UChannel::IsNetReady(bool Saturate)
{
static auto NumOutRecOffset = 0x4C;
if (*(int*)(__int64(this) + NumOutRecOffset) < 255)
{
static auto ConnectionOffset = GetOffset("Connection");
auto Connection = Get<UNetConnection*>(ConnectionOffset);
return Connection->IsNetReady(Saturate);
}
return 0;
}

View File

@@ -1,49 +0,0 @@
#pragma once
#include "Object.h"
#include "reboot.h"
#include "Map.h"
struct FTableRowBase
{
unsigned char UnknownData00[0x8]; // this is actually structural padding
};
class UDataTable : public UObject
{
public:
template <typename RowDataType = uint8_t>
TMap<FName, RowDataType*>& GetRowMap()
{
static auto RowStructOffset = FindOffsetStruct("/Script/Engine.DataTable", "RowStruct");
return *(TMap<FName, RowDataType*>*)(__int64(this) + (RowStructOffset + sizeof(UObject*))); // because after rowstruct is rowmap
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.DataTable");
return Class;
}
};
struct FDataTableRowHandle
{
UDataTable* DataTable; // 0x0000(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FName RowName; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
template <typename StructType = uint8>
struct RowNameAndRowData
{
FName RowName;
StructType* RowData;
};
struct FDataTableCategoryHandle
{
UDataTable* DataTable; // 0x0000(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FName ColumnName; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FName RowContents; // 0x0010(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};

View File

@@ -1,29 +0,0 @@
#include "DataTableFunctionLibrary.h"
#include "reboot.h"
float UDataTableFunctionLibrary::EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY,
const FString& ContextString, EEvaluateCurveTableResult* OutResult)
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.DataTableFunctionLibrary.EvaluateCurveTableRow");
float wtf{};
EEvaluateCurveTableResult wtf1{};
struct { UCurveTable* CurveTable; FName RowName; float InXY; EEvaluateCurveTableResult OutResult; float OutXY; FString ContextString; }
UDataTableFunctionLibrary_EvaluateCurveTableRow_Params{CurveTable, RowName, InXY, wtf1, wtf, ContextString};
static auto DefaultClass = StaticClass();
DefaultClass->ProcessEvent(fn, &UDataTableFunctionLibrary_EvaluateCurveTableRow_Params);
if (OutResult)
*OutResult = UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutResult;
return UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutXY;
}
UClass* UDataTableFunctionLibrary::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.DataTableFunctionLibrary");
return Class;
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include "Object.h"
#include "CurveTable.h"
#include "UnrealString.h"
enum class EEvaluateCurveTableResult : uint8_t
{
RowFound = 0,
RowNotFound = 1,
EEvaluateCurveTableResult_MAX = 2
};
class UDataTableFunctionLibrary : public UObject
{
public:
static float EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY,
const FString& ContextString = FString(), EEvaluateCurveTableResult* OutResult = nullptr);
static UClass* StaticClass();
};

View File

@@ -1,39 +0,0 @@
#pragma once
#include "inc.h"
#include "RemoveReference.h"
#include "RemoveCV.h"
namespace UE4Decay_Private
{
template <typename T>
struct TDecayNonReference
{
typedef typename TRemoveCV<T>::Type Type;
};
template <typename T>
struct TDecayNonReference<T[]>
{
typedef T* Type;
};
template <typename T, uint32 N>
struct TDecayNonReference<T[N]>
{
typedef T* Type;
};
template <typename RetType, typename... Params>
struct TDecayNonReference<RetType(Params...)>
{
typedef RetType(*Type)(Params...);
};
}
template <typename T>
struct TDecay
{
typedef typename UE4Decay_Private::TDecayNonReference<typename TRemoveReference<T>::Type>::Type Type;
};

View File

@@ -1,19 +0,0 @@
#pragma once
#include "DelegateBase.h"
#include "DelegateSignatureImpl.inl"
#define FUNC_CONCAT( ... ) __VA_ARGS__
#define FUNC_DECLARE_DELEGATE( DelegateName, ReturnType, ... ) \
typedef TBaseDelegate/*<__VA_ARGS__>*/ DelegateName;
#define FUNC_DECLARE_DYNAMIC_DELEGATE( TWeakPtr, DynamicDelegateName, ExecFunction, FuncParamList, FuncParamPassThru, ... ) \
class DynamicDelegateName : public TBaseDynamicDelegate<TWeakPtr, __VA_ARGS__> \
{ \
public: \
DynamicDelegateName() \
{ \
} \
\
};

View File

@@ -1,28 +0,0 @@
#pragma once
#include "inc.h"
#include "TypeCompatibleBytes.h"
#include "ContainerAllocationPolicies.h"
#if !defined(_WIN32) || defined(_WIN64)
// Let delegates store up to 32 bytes which are 16-byte aligned before we heap allocate
typedef TAlignedBytes<16, 16> FAlignedInlineDelegateType;
#if USE_SMALL_DELEGATES
typedef FHeapAllocator FDelegateAllocatorType;
#else
typedef TInlineAllocator<2> FDelegateAllocatorType;
#endif
#else
// ... except on Win32, because we can't pass 16-byte aligned types by value, as some delegates are
// so we'll just keep it heap-allocated, which are always sufficiently aligned.
typedef TAlignedBytes<16, 8> FAlignedInlineDelegateType;
typedef FHeapAllocator FDelegateAllocatorType;
#endif
class FDelegateBase
{
public:
FDelegateAllocatorType::ForElementType<FAlignedInlineDelegateType> DelegateAllocator;
int32 DelegateSize;
};

View File

@@ -1,7 +0,0 @@
#pragma once
#include "Delegate.h"
#include "ObjectMacros.h"
#define DECLARE_DELEGATE( DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, void )
#define DECLARE_DYNAMIC_DELEGATE( DelegateName ) /* BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) */ FUNC_DECLARE_DYNAMIC_DELEGATE( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, , FUNC_CONCAT( *this ), void )

View File

@@ -1,16 +0,0 @@
#pragma once
template <bool Const, typename Class, typename FuncType>
struct TMemFunPtrType;
template <typename Class, typename RetType, typename... ArgTypes>
struct TMemFunPtrType<false, Class, RetType(ArgTypes...)>
{
typedef RetType(Class::* Type)(ArgTypes...);
};
template <typename Class, typename RetType, typename... ArgTypes>
struct TMemFunPtrType<true, Class, RetType(ArgTypes...)>
{
typedef RetType(Class::* Type)(ArgTypes...) const;
};

View File

@@ -1,63 +0,0 @@
#pragma once
#include "DelegateBase.h"
#include "ScriptDelegates.h"
#include "DelegateInstanceInterface.h"
#include "RemoveReference.h"
#include "TypeWrapper.h"
// template <typename WrappedRetValType, typename... ParamTypes> // (Milxnor) IDK IM SCUFFED
class TBaseDelegate : public FDelegateBase
{
public:
// (Milxnor) YEAH NO
/*
typedef typename TUnwrapType<WrappedRetValType>::Type RetValType;
template <typename UserClass, typename... VarTypes>
FUNCTION_CHECK_RETURN_START
inline static TBaseDelegate<RetValType, ParamTypes...> CreateRaw(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
FUNCTION_CHECK_RETURN_END
{
// UE_STATIC_DEPRECATE(4.23, TIsConst<UserClass>::Value, "Binding a delegate with a const object pointer and non-const function is deprecated.");
TBaseDelegate<RetValType, ParamTypes...> Result;
TBaseRawMethodDelegateInstance<false, UserClass, TFuncType, VarTypes...>::Create(Result, InUserObject, InFunc, Vars...);
return Result;
}
template <typename UserClass, typename... VarTypes>
FUNCTION_CHECK_RETURN_START
inline static TBaseDelegate<RetValType, ParamTypes...> CreateRaw(UserClass* InUserObject, typename TMemFunPtrType<true, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
FUNCTION_CHECK_RETURN_END
{
TBaseDelegate<RetValType, ParamTypes...> Result;
TBaseRawMethodDelegateInstance<true, UserClass, TFuncType, VarTypes...>::Create(Result, InUserObject, InFunc, Vars...);
return Result;
}
template <typename UserClass, typename... VarTypes>
inline void BindRaw(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
{
// UE_STATIC_DEPRECATE(4.23, TIsConst<UserClass>::Value, "Binding a delegate with a const object pointer and non-const function is deprecated.");
*this = CreateRaw(const_cast<typename TRemoveConst<UserClass>::Type*>(InUserObject), InFunc, Vars...);
}
template <typename UserClass, typename... VarTypes>
inline void BindRaw(UserClass* InUserObject, typename TMemFunPtrType<true, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
{
*this = CreateRaw(InUserObject, InFunc, Vars...);
} */
};
template <typename TWeakPtr, typename RetValType, typename... ParamTypes>
class TBaseDynamicDelegate : public TScriptDelegate<TWeakPtr>
{
public:
/**
* Default constructor
*/
TBaseDynamicDelegate() { }
};

View File

@@ -1,15 +0,0 @@
#pragma once
template <bool Predicate, typename Result = void>
class TEnableIf;
template <typename Result>
class TEnableIf<true, Result>
{
public:
typedef Result Type;
};
template <typename Result>
class TEnableIf<false, Result>
{ };

View File

@@ -1,17 +0,0 @@
#pragma once
#include "World.h"
#include "NetDriver.h"
#include "UnrealString.h"
class UEngine : public UObject
{
public:
static inline UNetDriver* (*Engine_CreateNetDriver)(UEngine* Engine, UWorld* InWorld, FName NetDriverDefinition);
UNetDriver* CreateNetDriver(UWorld* InWorld, FName NetDriverDefinition) { return Engine_CreateNetDriver(this, InWorld, NetDriverDefinition); }
};
// static inline bool (*CreateNamedNetDriver)(UWorld* InWorld, FName NetDriverName, FName NetDriverDefinition);
// static inline UNetDriver* CreateNetDriver_Local(UEngine* Engine, FWorldContext& Context, FName NetDriverDefinition)

View File

@@ -1,33 +0,0 @@
#include "EngineTypes.h"
#include "reboot.h"
UStruct* FHitResult::GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/Engine.HitResult");
return Struct;
}
int FHitResult::GetStructSize()
{
return GetStruct()->GetPropertiesSize();
}
bool FHitResult::IsBlockingHit()
{
// return true;
static auto bBlockingHitOffset = FindOffsetStruct("/Script/Engine.HitResult", "bBlockingHit");
static auto bBlockingHitFieldMask = GetFieldMask(FindPropertyStruct("/Script/Engine.HitResult", "bBlockingHit"));
return ReadBitfield((PlaceholderBitfield*)(__int64(this) + bBlockingHitOffset), bBlockingHitFieldMask);
}
FVector& FHitResult::GetLocation()
{
static auto LocationOffset = FindOffsetStruct("/Script/Engine.HitResult", "Location");
return *(FVector*)(__int64(this) + LocationOffset);
}
void FHitResult::CopyFromHitResult(FHitResult* Other)
{
this->GetLocation() = Other->GetLocation();
}

View File

@@ -1,95 +0,0 @@
#pragma once
#include "Object.h"
#include "Vector.h"
#include "DelegateCombinations.h"
enum class ESpawnActorCollisionHandlingMethod : uint8
{
Undefined,
AlwaysSpawn,
AdjustIfPossibleButAlwaysSpawn,
AdjustIfPossibleButDontSpawnIfColliding,
DontSpawnIfColliding
};
struct FHitResult
{
static class UStruct* GetStruct();
static int GetStructSize();
bool IsBlockingHit();
FVector& GetLocation();
void CopyFromHitResult(FHitResult* Other);
};
struct FTimerHandle
{
FTimerHandle()
: Handle(0)
{
}
/** True if this handle was ever initialized by the timer manager */
bool IsValid() const
{
return Handle != 0;
}
/** Explicitly clear handle */
void Invalidate()
{
Handle = 0;
}
bool operator==(const FTimerHandle& Other) const
{
return Handle == Other.Handle;
}
bool operator!=(const FTimerHandle& Other) const
{
return Handle != Other.Handle;
}
/* FString ToString() const
{
return FString::Printf(TEXT("%llu"), Handle);
} */
// private:
static const uint32 IndexBits = 24;
static const uint32 SerialNumberBits = 40;
static_assert(IndexBits + SerialNumberBits == 64, "The space for the timer index and serial number should total 64 bits");
static const int32 MaxIndex = (int32)1 << IndexBits;
static const uint64 MaxSerialNumber = (uint64)1 << SerialNumberBits;
void SetIndexAndSerialNumber(int32 Index, uint64 SerialNumber)
{
// check(Index >= 0 && Index < MaxIndex);
// check(SerialNumber < MaxSerialNumber);
Handle = (SerialNumber << IndexBits) | (uint64)(uint32)Index;
}
FORCEINLINE int32 GetIndex() const
{
return (int32)(Handle & (uint64)(MaxIndex - 1));
}
FORCEINLINE uint64 GetSerialNumber() const
{
return Handle >> IndexBits;
}
uint64 Handle;
/* friend uint32 GetTypeHash(const FTimerHandle& InHandle)
{
return GetTypeHash(InHandle.Handle);
} */
};
DECLARE_DYNAMIC_DELEGATE(FTimerDynamicDelegate);

View File

@@ -1,8 +0,0 @@
#pragma once
#include "Object.h"
class UEnvQuery : public UObject // UDataAsset
{
public:
};

View File

@@ -1,18 +0,0 @@
#pragma once
#include "NameTypes.h"
enum class EAIParamType : uint8
{
Float,
Int,
Bool
// MAX UMETA(Hidden)
};
struct FEnvNamedValue // i dont thin kthis ever changes
{
FName ParamName;
EAIParamType ParamType;
float Value;
};

View File

@@ -1 +0,0 @@
#pragma once

Some files were not shown because too many files have changed in this diff Show More