diff --git a/Project Reboot 3.0/BuildingWeapons.h b/Project Reboot 3.0/BuildingWeapons.h index 56b89fe..506b3e1 100644 --- a/Project Reboot 3.0/BuildingWeapons.h +++ b/Project Reboot 3.0/BuildingWeapons.h @@ -14,6 +14,8 @@ class AFortWeap_BuildingTool : public AFortWeap_BuildingToolBase class AFortWeap_EditingTool : public AFortWeap_BuildingToolBase { public: + static inline void (*originalOnRep_EditActor)(AFortWeap_EditingTool*); + ABuildingSMActor*& GetEditActor() { static auto EditActorOffset = GetOffset("EditActor"); @@ -27,7 +29,7 @@ public: // if (HasAuthority()) { GetEditActor() = EditActor; - OnRep_EditActor(); + originalOnRep_EditActor(this); } } diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 72d77b6..c7c9b6f 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -53,6 +53,13 @@ void AFortPlayerController::ClientEquipItem(const FGuid& ItemGuid, bool bForceEx } } +void AFortPlayerController::ClientForceCancelBuildingTool() +{ + static auto ClientForceCancelBuildingToolFn = FindObject(L"/Script/FortniteGame.FortPlayerController.ClientForceCancelBuildingTool"); + + this->ProcessEvent(ClientForceCancelBuildingToolFn); +} + bool AFortPlayerController::DoesBuildFree() { if (Globals::bInfiniteMaterials) @@ -963,6 +970,7 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra ExistingBuildings.Free(); + // BuildingActor->SetCurrentBuildingLevel() BuildingActor->SetPlayerPlaced(true); BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true); BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required? @@ -1676,6 +1684,23 @@ bool IsOkForEditing(ABuildingSMActor* BuildingActor, AFortPlayerController* Cont Idk(BuildingActor); } +/* + +The editing dilemma: + +15.10: +Valid edit pattern: +ServerBeginEditingActorblahblah +ServerEdit +ClientForceStop + +WHERE IS END EDITING?!?!??! +Invalid EDitPattern: +ServerBeginEditingActorblahblah +ServerEnd + +*/ + void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit) { if (!BuildingActorToEdit || !BuildingActorToEdit->IsPlayerPlaced()) // We need more checks. @@ -1738,7 +1763,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame // LOG_INFO(LogDev, "RotationIterations: {}", RotationIterations); - if (!BuildingActorToEdit || !NewBuildingClass || BuildingActorToEdit->IsDestroyed() || BuildingActorToEdit->GetEditingPlayer() != PlayerState) + if (!BuildingActorToEdit || !NewBuildingClass || BuildingActorToEdit->GetEditingPlayer() != PlayerState || BuildingActorToEdit->IsDestroyed()) { // LOG_INFO(LogDev, "Cheater?"); // LOG_INFO(LogDev, "BuildingActorToEdit->GetEditingPlayer(): {} PlayerState: {} NewBuildingClass: {} BuildingActorToEdit: {}", BuildingActorToEdit ? __int64(BuildingActorToEdit->GetEditingPlayer()) : -1, __int64(PlayerState), __int64(NewBuildingClass), __int64(BuildingActorToEdit)); @@ -1764,7 +1789,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame return ServerEditBuildingActorOriginal(Context, Stack, Ret); } -void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing) +void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing) { auto Pawn = PlayerController->GetMyFortPawn(); @@ -1782,15 +1807,17 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl if (!WorldInventory) return; - AFortWeap_EditingTool* EditTool = Cast(Pawn->GetCurrentWeapon()); + auto EditToolInstance = WorldInventory->FindItemInstance(EditToolDef); - if (EditTool) + if (!EditToolInstance) + return; + + // Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); // why do they do this on older builds bru + + if (auto EditTool = Cast(Pawn->GetCurrentWeapon())) { - static auto bEditConfirmedOffset = EditTool->GetOffset("bEditConfirmed"); - - if (bEditConfirmedOffset != -1) - EditTool->Get(bEditConfirmedOffset) = true; // this probably does nothing on server - EditTool->SetEditActor(nullptr); } + + PlayerController->ClientForceCancelBuildingTool(); } diff --git a/Project Reboot 3.0/FortPlayerController.h b/Project Reboot 3.0/FortPlayerController.h index 5137b80..bc55a0e 100644 --- a/Project Reboot 3.0/FortPlayerController.h +++ b/Project Reboot 3.0/FortPlayerController.h @@ -188,6 +188,7 @@ public: } void ClientEquipItem(const FGuid& ItemGuid, bool bForceExecution); + void ClientForceCancelBuildingTool(); bool DoesBuildFree(); void DropAllItems(const std::vector& IgnoreItemDefs, bool bIgnoreSecondaryQuickbar = false, bool bRemoveIfNotDroppable = false, bool RemovePickaxe = false); diff --git a/Project Reboot 3.0/die.h b/Project Reboot 3.0/die.h index 277be65..b76e421 100644 --- a/Project Reboot 3.0/die.h +++ b/Project Reboot 3.0/die.h @@ -2,11 +2,6 @@ #include "reboot.h" #include "FortGameModeAthena.h" -#include "GameplayStatics.h" -#include "CurveTable.h" -#include "KismetStringLibrary.h" -#include "DataTableFunctionLibrary.h" -#include "FortPlaysetItemDefinition.h" extern inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK) = nullptr; diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 5b1dc47..edb2ae9 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -16,6 +16,7 @@ #include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" #include "FortGameStateAthena.h" #include "BuildingGameplayActorSpawnMachine.h" +#include "BuildingWeapons.h" #include "BuildingFoundation.h" #include "Map.h" @@ -1169,6 +1170,26 @@ DWORD WINAPI Main(LPVOID) nullptr, false); } + auto OnRep_EditActorFn = FindObject(L"/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor"); + + if (OnRep_EditActorFn) + { + auto OnRep_EditActorExec = (uint64)OnRep_EditActorFn->GetFunc(); + uint64 OnRep_EditActorOriginal = 0; + + for (int i = 0; i < 400; i++) + { + if (*(uint8_t*)(OnRep_EditActorExec + i) == 0xE8 || *(uint8_t*)(OnRep_EditActorExec + i) == 0xE9) + { + OnRep_EditActorOriginal = Memcury::Scanner(OnRep_EditActorExec + i).RelativeOffset(1).Get(); + break; + } + } + + LOG_INFO(LogDev, "OnRep_EditActor Offset: {}", OnRep_EditActorOriginal - __int64(GetModuleHandleW(0))); + AFortWeap_EditingTool::originalOnRep_EditActor = decltype(AFortWeap_EditingTool::originalOnRep_EditActor)(OnRep_EditActorOriginal); + } + static auto ServerReturnToMainMenuFn = FindObject(L"/Script/FortniteGame.FortPlayerController.ServerReturnToMainMenu"); static auto ServerReturnToMainMenuIdx = GetFunctionIdxOrPtr(ServerReturnToMainMenuFn) / 8; auto FortServerRestartPlayer = FortPlayerControllerDefault->VFTable[ServerReturnToMainMenuIdx]; @@ -1566,10 +1587,6 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal); Hooking::MinHook::Hook((PVOID)Addresses::EnterAircraft, (PVOID)AFortPlayerControllerAthena::EnterAircraftHook, (PVOID*)&AFortPlayerControllerAthena::EnterAircraftOriginal); -#ifndef PROD - Hooking::MinHook::Hook((PVOID)Addresses::ProcessEvent, ProcessEventHook, (PVOID*)&UObject::ProcessEventOriginal); -#endif - AddVehicleHook(); auto ClientOnPawnDiedCallAddr = FindFunctionCall(L"ClientOnPawnDied", Engine_Version == 416 ? std::vector{ 0x48, 0x89, 0x54 } : std::vector{ 0x48, 0x89, 0x5C }); diff --git a/Project Reboot 3.0/finder.cpp b/Project Reboot 3.0/finder.cpp index 3073bd8..e42e1cb 100644 --- a/Project Reboot 3.0/finder.cpp +++ b/Project Reboot 3.0/finder.cpp @@ -52,7 +52,7 @@ uint64 FindGIsClient() std::vector> BytesArray = { {0x88, 0x05}, // 20.40 21.00 - {0xC6, 0x05}, // mov cs X // Checked on 1.11, 12.41 + {0xC6, 0x05}, // mov cs X // Checked on 1.11, 12.41, 15.10 {0x88, 0x1D}, // mov cs bl // Checked on 17.50, 19.10 {0x44, 0x88} // 4.5 }; @@ -60,6 +60,7 @@ uint64 FindGIsClient() int Skip = 2; uint64 Addy = 0; + int PickedByte = 0; for (int i = 0; i < 50; i++) // we should subtract from skip if go up { @@ -98,6 +99,13 @@ uint64 FindGIsClient() continue; } + if (!PickedByte) + { + PickedByte = Bytes[0]; + } + else if (PickedByte != Bytes[0]) + continue; // Its one of the bytes, but not the first one we found. + if (Skip > 0) { Skip--; diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h index 856b9d8..bfda065 100644 --- a/Project Reboot 3.0/globals.h +++ b/Project Reboot 3.0/globals.h @@ -24,6 +24,7 @@ namespace Globals extern inline bool bAutoRestart = false; // doesnt work fyi extern inline bool bFillVendingMachines = true; extern inline int AmountOfListens = 0; // TODO: Switch to this for LastNum + extern inline bool bDeveloperMode = false; } extern inline int NumToSubtractFromSquadId = 0; // I think 2? diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index 27a997d..b1a99b9 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -35,6 +35,7 @@ #include "GameplayStatics.h" #include "Text.h" #include +#include "hooking.h" #include "FortGadgetItemDefinition.h" #include "FortWeaponItemDefinition.h" #include "events.h" @@ -325,10 +326,18 @@ static inline void StaticUI() ImGui::InputInt("Shield/Health for siphon", &AmountOfHealthSiphon); -#ifndef PROD - ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent); + ImGui::Checkbox("Enable Developer Mode", &Globals::bDeveloperMode); + + if (Globals::bDeveloperMode) + { + if (ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent)) + { + // todo toggle hook + Hooking::MinHook::Hook((PVOID)Addresses::ProcessEvent, ProcessEventHook, (PVOID*)&UObject::ProcessEventOriginal); + } + } + // ImGui::InputInt("Amount of bots to spawn", &AmountOfBotsToSpawn); -#endif ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo); ImGui::Checkbox("Infinite Materials", &Globals::bInfiniteMaterials); @@ -444,23 +453,24 @@ static inline void MainTabs() // maybe a Replication Stats for >3.3? -#ifndef PROD - if (ImGui::BeginTabItem("Developer")) + if (Globals::bDeveloperMode) { - Tab = DEVELOPER_TAB; - PlayerTab = -1; - bInformationTab = false; - ImGui::EndTabItem(); - } + if (ImGui::BeginTabItem("Developer")) + { + Tab = DEVELOPER_TAB; + PlayerTab = -1; + bInformationTab = false; + ImGui::EndTabItem(); + } - if (ImGui::BeginTabItem("Debug Logs")) - { - Tab = DEBUGLOG_TAB; - PlayerTab = -1; - bInformationTab = false; - ImGui::EndTabItem(); + if (ImGui::BeginTabItem("Debug Logs")) + { + Tab = DEBUGLOG_TAB; + PlayerTab = -1; + bInformationTab = false; + ImGui::EndTabItem(); + } } -#endif if (false && ImGui::BeginTabItem(("Credits"))) { diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index f542149..ae53a99 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -357,14 +357,22 @@ namespace Hooking static bool Unhook(void* Addr) { - return MH_DisableHook((PVOID)Addr) == MH_OK; - } + bool bWasUnHookSuccessful = MH_DisableHook((PVOID)Addr) == MH_OK; - /* static bool Unhook(void** Addr, void* Original) // I got brain damaged - { - Unhook(Addr); - *Addr = Original; - } */ + if (bWasUnHookSuccessful) + { + for (auto it = AllFunctionHooks.begin(); it != AllFunctionHooks.end(); it++) + { + if (it->Original == Addr) + { + AllFunctionHooks.erase(it); + break; + } + } + } + + return bWasUnHookSuccessful; + } } } diff --git a/Project Reboot 3.0/inc.h b/Project Reboot 3.0/inc.h index 0d61e5a..745b792 100644 --- a/Project Reboot 3.0/inc.h +++ b/Project Reboot 3.0/inc.h @@ -20,7 +20,11 @@ extern inline int Engine_Version = 0; // For example, 420, 421, etc. // Prevent extern inline double Fortnite_Version = 0; // For example, 4.1, 6.21, etc. // Prevent using this when possible. extern inline int Fortnite_CL = 0; -#define PROD // this doesnt do anything besides remove processeventhook and some assert stuff +// #define PROD // this doesnt do anything besides remove processeventhook and some assert stuff +// DEPRACTERD ^^^ + + + // #define ABOVE_S20 struct PlaceholderBitfield