diff --git a/Project Reboot 3.0/Actor.cpp b/Project Reboot 3.0/Actor.cpp index 5c5fa8a..20b3382 100644 --- a/Project Reboot 3.0/Actor.cpp +++ b/Project Reboot 3.0/Actor.cpp @@ -141,6 +141,20 @@ bool AActor::IsOnlyRelevantToOwner() return ReadBitfieldValue(bOnlyRelevantToOwnerOffset, bOnlyRelevantToOwnerFieldMask); } +bool AActor::CanBeDamaged() +{ + static auto bCanBeDamagedOffset = GetOffset("bCanBeDamaged"); + static auto bCanBeDamagedFieldMask = GetFieldMask(GetProperty("bOnlyRelevantToOwner")); + return ReadBitfieldValue(bCanBeDamagedOffset, bCanBeDamagedFieldMask); +} + +void AActor::SetCanBeDamaged(bool NewValue) +{ + static auto bCanBeDamagedOffset = GetOffset("bCanBeDamaged"); + static auto bCanBeDamagedFieldMask = GetFieldMask(GetProperty("bOnlyRelevantToOwner")); + SetBitfieldValue(bCanBeDamagedOffset, bCanBeDamagedFieldMask, NewValue); +} + UClass* AActor::StaticClass() { static auto Class = FindObject(L"/Script/Engine.Actor"); diff --git a/Project Reboot 3.0/Actor.h b/Project Reboot 3.0/Actor.h index 833cb2a..030b75c 100644 --- a/Project Reboot 3.0/Actor.h +++ b/Project Reboot 3.0/Actor.h @@ -21,6 +21,8 @@ public: bool IsAlwaysRelevant(); bool UsesOwnerRelevancy(); bool IsOnlyRelevantToOwner(); + bool CanBeDamaged(); + void SetCanBeDamaged(bool NewValue); void SetOwner(AActor* Owner); static class UClass* StaticClass(); diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 9aa259d..b4ab954 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -253,17 +253,17 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game GameState->OnRep_CurrentPlaylistInfo(); }; - auto& LocalPlayers = GetLocalPlayers(); + /* auto& LocalPlayers = GetLocalPlayers(); if (LocalPlayers.Num() && LocalPlayers.Data) { LocalPlayers.Remove(0); - } - - // LOG_INFO(LogDev, "ReadyToStartMatch!"); + } */ static int LastNum2 = 1; + // LOG_INFO(LogDev, "ReadyToStartMatch AmountOfRestarts: {} LastNum2: {}!", AmountOfRestarts, LastNum2); + if (AmountOfRestarts != LastNum2) { LastNum2 = AmountOfRestarts; diff --git a/Project Reboot 3.0/World.cpp b/Project Reboot 3.0/World.cpp index b932228..fe7af7d 100644 --- a/Project Reboot 3.0/World.cpp +++ b/Project Reboot 3.0/World.cpp @@ -21,7 +21,7 @@ void UWorld::Listen() constexpr bool bUseBeacons = true; - int Port = 7777; + int Port = 7777 - AmountOfRestarts; if (bUseBeacons) { diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index 03ff3e8..4360c0d 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -185,6 +185,101 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) SendMessageToConsole(PlayerController, L"Granted item!"); } + else if (Command == "launch") + { + if (Arguments.size() <= 3) + { + SendMessageToConsole(PlayerController, L"Please provide X, Y, and Z!\n"); + return; + } + + float X{}, Y{}, Z{}; + + try { X = std::stof(Arguments[1]); } + catch (...) {} + try { Y = std::stof(Arguments[2]); } + catch (...) {} + try { Z = std::stof(Arguments[3]); } + catch (...) {} + + auto Pawn = ReceivingController->GetMyFortPawn(); + + if (!Pawn) + { + SendMessageToConsole(PlayerController, L"No pawn to teleport!"); + return; + } + + static auto LaunchCharacterFn = FindObject("/Script/Engine.Character.LaunchCharacter"); + + struct + { + FVector LaunchVelocity; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bXYOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bZOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } ACharacter_LaunchCharacter_Params{ FVector(X, Y, Z), false, false}; + Pawn->ProcessEvent(LaunchCharacterFn, &ACharacter_LaunchCharacter_Params); + SendMessageToConsole(PlayerController, L"Launched character!"); + } + else if (Command == "setshield") + { + auto Pawn = ReceivingController->GetMyFortPawn(); + + if (!Pawn) + { + SendMessageToConsole(PlayerController, L"No pawn!"); + return; + } + + float Shield = 0.f; + + if (NumArgs >= 1) + { + try { Shield = std::stof(Arguments[1]); } + catch (...) {} + } + + Pawn->SetShield(Shield); + SendMessageToConsole(PlayerController, L"Set shield!\n"); + } + /* else if (Command == "god") + { + auto Pawn = ReceivingController->GetMyFortPawn(); + + if (!Pawn) + { + SendMessageToConsole(PlayerController, L"No pawn!"); + return; + } + + Pawn->SetCanBeDamaged(!Pawn->CanBeDamaged()); + SendMessageToConsole(PlayerController, std::wstring(L"God set to " + std::to_wstring(!(bool)Pawn->CanBeDamaged())).c_str()); + } + else if (Command == "applycid") + { + auto PlayerState = Cast(ReceivingController->GetPlayerState()); + + if (!PlayerState) // ??? + { + SendMessageToConsole(PlayerController, L"No playerstate!"); + return; + } + + auto Pawn = Cast(ReceivingController->GetMyFortPawn()); + + std::string CIDStr = Arguments[1]; + auto CIDDef = FindObject(CIDStr, nullptr, ANY_PACKAGE); + // auto CIDDef = UObject::FindObject(CIDStr); + + if (!CIDDef) + { + SendMessageToConsole(PlayerController, L"Invalid character item definition!"); + return; + } + + ApplyCID(Pawn, CIDDef); + SendMessageToConsole(PlayerController, L"Applied CID!"); + } */ else if (Command == "summon") { if (Arguments.size() <= 1) diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 5d37c11..2cf5f1a 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -103,15 +103,6 @@ DWORD WINAPI Main(LPVOID) UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFort VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogGameMode VeryVerbose", nullptr); - static auto SwitchLevel = FindObject(L"/Script/Engine.PlayerController.SwitchLevel"); - FString Level = Engine_Version < 424 - ? L"Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 - ? L"Asteria_Terrain" - : Globals::bCreative ? L"Creative_NoApollo_Terrain" - : L"Artemis_Terrain" - : Globals::bCreative ? L"Creative_NoApollo_Terrain" - : L"Apollo_Terrain"; - if (Globals::bNoMCP) { if (Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr)) @@ -129,10 +120,6 @@ DWORD WINAPI Main(LPVOID) LOG_INFO(LogDev, "Size: 0x{:x}", sizeof(TMap)); - GetLocalPlayerController()->ProcessEvent(SwitchLevel, &Level); - - LOG_INFO(LogPlayer, "Switched level."); - Hooking::MinHook::Hook((PVOID)Addresses::ActorGetNetMode, (PVOID)GetNetModeHook2, nullptr); LOG_INFO(LogDev, "FindGIsServer: 0x{:x}", FindGIsServer() - __int64(GetModuleHandleW(0))); @@ -147,6 +134,50 @@ DWORD WINAPI Main(LPVOID) *(bool*)FindGIsClient() = false; } + bool bUseSwitchLevel = false; + + if (bUseSwitchLevel) + { + static auto SwitchLevel = FindObject(L"/Script/Engine.PlayerController.SwitchLevel"); + FString Level = Engine_Version < 424 + ? L"Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 + ? L"Asteria_Terrain" + : Globals::bCreative ? L"Creative_NoApollo_Terrain" + : L"Artemis_Terrain" + : Globals::bCreative ? L"Creative_NoApollo_Terrain" + : L"Apollo_Terrain"; + + GetLocalPlayerController()->ProcessEvent(SwitchLevel, &Level); + } + else + { + if (true) + { + auto& LocalPlayers = GetLocalPlayers(); + + if (LocalPlayers.Num() && LocalPlayers.Data) + { + LocalPlayers.Remove(0); + } + } + else if (false) + { + UGameplayStatics::RemovePlayer((APlayerController*)GetLocalPlayerController(), true); + } + + FString LevelB = Engine_Version < 424 + ? L"open Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 + ? L"open Asteria_Terrain" + : Globals::bCreative ? L"open Creative_NoApollo_Terrain" + : L"open Artemis_Terrain" + : Globals::bCreative ? L"open Creative_NoApollo_Terrain" + : L"open Apollo_Terrain"; + + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), LevelB, nullptr); + } + + LOG_INFO(LogPlayer, "Switched level."); + if (Fortnite_Version == 17.30) { // Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E07910), (PVOID)Return2Hook, nullptr); @@ -154,18 +185,21 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED158), (PVOID)ReturnTrueHook, nullptr); } - if (true) + if (bUseSwitchLevel) { - auto& LocalPlayers = GetLocalPlayers(); - - if (LocalPlayers.Num() && LocalPlayers.Data) + if (true) { - LocalPlayers.Remove(0); + auto& LocalPlayers = GetLocalPlayers(); + + if (LocalPlayers.Num() && LocalPlayers.Data) + { + LocalPlayers.Remove(0); + } + } + else if (false) + { + UGameplayStatics::RemovePlayer((APlayerController*)GetLocalPlayerController(), true); } - } - else if (false) - { - UGameplayStatics::RemovePlayer((APlayerController*)GetLocalPlayerController(), true); } for (auto func : Addresses::GetFunctionsToNull()) @@ -481,7 +515,7 @@ DWORD WINAPI Main(LPVOID) Globals::bLogProcessEvent = !Globals::bLogProcessEvent; } - /* else if (GetAsyncKeyState(VK_F10) & 1) + else if (GetAsyncKeyState(VK_F10) & 1) { FString LevelA = Engine_Version < 424 ? L"open Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 @@ -507,7 +541,7 @@ DWORD WINAPI Main(LPVOID) // UGameplayStatics::OpenLevel(GetWorld(), UKismetStringLibrary::Conv_StringToName(LevelA), true, FString()); LOG_INFO(LogDev, "Restarting!"); AmountOfRestarts++; - } */ + } Sleep(1000 / 30); } diff --git a/Project Reboot 3.0/log.h b/Project Reboot 3.0/log.h index 063c4c3..7bf488c 100644 --- a/Project Reboot 3.0/log.h +++ b/Project Reboot 3.0/log.h @@ -43,7 +43,9 @@ inline void InitLogger() FILE* stream = nullptr; - // if (false) + bool bStopFortniteOutput = true; + + if (bStopFortniteOutput) { freopen_s(&stream, "in.txt", "r", stdin); freopen_s(&stream, "out.txt", "w+", stdout); diff --git a/Project Reboot 3.0/reboot.h b/Project Reboot 3.0/reboot.h index ce46b9e..e903972 100644 --- a/Project Reboot 3.0/reboot.h +++ b/Project Reboot 3.0/reboot.h @@ -129,7 +129,7 @@ static __forceinline T* Cast(UObject* Object, bool bCheckType = true) return nullptr; } -static inline int AmountOfRestarts = 0; +extern inline int AmountOfRestarts = 0; struct PlaceholderBitfield { diff --git a/README.md b/README.md index 1681bc2..2da8b18 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,6 @@ F8 - Start Aircraft ## TODO -- Rewrite picking up code. \ No newline at end of file +- Rewrite picking up code. +- Rewrite dllmain +- Move hooking to each class (for example, AFortGameModeAthena::InitHooks). \ No newline at end of file