From 2335ad43a3e20f9f08e7594d64b6b8567ae6dd7b Mon Sep 17 00:00:00 2001 From: Milxnor Date: Fri, 12 May 2023 19:03:57 -0400 Subject: [PATCH] spectacular fix s16+ no reserve (again), fix ltm crash on loot (again), fix s3-s6 respawning --- Project Reboot 3.0/FortGameModeAthena.h | 6 +- Project Reboot 3.0/FortLootPackage.cpp | 11 +- Project Reboot 3.0/FortPlayerPawn.cpp | 2 +- Project Reboot 3.0/GameModeBase.cpp | 182 +++++++++++++----------- Project Reboot 3.0/addresses.cpp | 20 +-- Project Reboot 3.0/dllmain.cpp | 8 +- Project Reboot 3.0/finder.h | 2 + 7 files changed, 126 insertions(+), 105 deletions(-) diff --git a/Project Reboot 3.0/FortGameModeAthena.h b/Project Reboot 3.0/FortGameModeAthena.h index a637fd7..24f692c 100644 --- a/Project Reboot 3.0/FortGameModeAthena.h +++ b/Project Reboot 3.0/FortGameModeAthena.h @@ -120,8 +120,10 @@ static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true) static auto StartEnabled_Dynamic = 2; static auto Static = 0; - static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType"); - BuildingFoundation->Get(DynamicFoundationTypeOffset) = bShow ? Static : StartDisabled; + static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType", false); + + if (DynamicFoundationTypeOffset != -1) + BuildingFoundation->Get(DynamicFoundationTypeOffset) = bShow ? Static : StartDisabled; /* static auto bShowHLODWhenDisabledOffset = BuildingFoundation->GetOffset("bShowHLODWhenDisabled", false); diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index e8bdd06..67b00c6 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -16,14 +16,19 @@ struct FFortGameFeatureLootTableData #ifdef EXPERIMENTAL_LOOTING template -void CollectDataTablesRows(std::vector DataTables, std::map* OutMap, std::function Check = []() { return true; }) +void CollectDataTablesRows(const std::vector& DataTables, std::map* OutMap, std::function Check = []() { return true; }) { std::vector DataTablesToIterate; - static auto CompositeDataTableClass = FindObject("/Script/Engine.CompositeDataTable"); + static auto CompositeDataTableClass = FindObject(L"/Script/Engine.CompositeDataTable"); - for (auto DataTable : DataTables) + for (UDataTable* DataTable : DataTables) { + if (!DataTable->IsValidLowLevel()) + { + continue; // Remove from vector? + } + // if (auto CompositeDataTable = Cast(DataTable)) if (DataTable->IsA(CompositeDataTableClass)) { diff --git a/Project Reboot 3.0/FortPlayerPawn.cpp b/Project Reboot 3.0/FortPlayerPawn.cpp index 3f8c1ed..a3e42a8 100644 --- a/Project Reboot 3.0/FortPlayerPawn.cpp +++ b/Project Reboot 3.0/FortPlayerPawn.cpp @@ -259,7 +259,7 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp"); - LOG_INFO(LogDev, "InFlyTime: {}", InFlyTime); + // LOG_INFO(LogDev, "InFlyTime: {}", InFlyTime); if (Pickup->Get(bPickedUpOffset)) { diff --git a/Project Reboot 3.0/GameModeBase.cpp b/Project Reboot 3.0/GameModeBase.cpp index c59d8c4..5592d12 100644 --- a/Project Reboot 3.0/GameModeBase.cpp +++ b/Project Reboot 3.0/GameModeBase.cpp @@ -55,13 +55,19 @@ AActor* AGameModeBase::K2_FindPlayerStart(AController* Player, FString IncomingN APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot) { - // LOG_INFO(LogDev, "SpawnDefaultPawnFor: 0x{:x}!", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); + auto NewPlayerAsAthena = Cast(NewPlayer); - // auto PawnClass = GameMode->GetDefaultPawnClassForController(NewPlayer); - // LOG_INFO(LogDev, "PawnClass: {}", PawnClass->GetFullName()); + if (!NewPlayerAsAthena) + return nullptr; // return original? + + auto PlayerStateAthena = NewPlayerAsAthena->GetPlayerStateAthena(); + + if (!PlayerStateAthena) + return nullptr; // return original? static auto PawnClass = FindObject("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C"); - GameMode->Get("DefaultPawnClass") = PawnClass; + static auto DefaultPawnClassOffset = GameMode->GetOffset("DefaultPawnClass"); + GameMode->Get(DefaultPawnClassOffset) = PawnClass; constexpr bool bUseSpawnActor = false; @@ -92,95 +98,111 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll bool bIsRespawning = false; + static auto RespawnDataOffset = PlayerStateAthena->GetOffset("RespawnData", false); + + if (RespawnDataOffset != -1) + { + static auto bServerIsReadyOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bServerIsReady"); + static auto bRespawnDataAvailableOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bRespawnDataAvailable"); + + auto RespawnDataPtr = PlayerStateAthena->GetPtr<__int64>(RespawnDataOffset); + + if (*(bool*)(__int64(RespawnDataPtr) + bServerIsReadyOffset) && *(bool*)(__int64(RespawnDataPtr) + bRespawnDataAvailableOffset)) // && GameState->IsRespawningAllowed(PlayerState); + { + // SpawnTransform.Translation = PlayerState->RespawnData.RespawnLocation; + // SpawnTransform.Rotation = Quaternion(PlayerState->RespawnData.RespawnRotation); + + bIsRespawning = true; + } + } + + auto ASC = PlayerStateAthena->GetAbilitySystemComponent(); + auto GameState = ((AFortGameModeAthena*)GameMode)->GetGameStateAthena(); + + GET_PLAYLIST(GameState); + + if (CurrentPlaylist) // Apply gameplay effects from playlist // We need to move this maybe? + { + CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena); + } + + auto PlayerAbilitySet = GetPlayerAbilitySet(); // Apply default gameplay effects // We need to move maybe? + + if (PlayerAbilitySet && ASC) + { + PlayerAbilitySet->ApplyGrantedGameplayAffectsToAbilitySystem(ASC); + } + if (!bIsRespawning) { - auto NewPlayerAsAthena = Cast(NewPlayer); + auto WorldInventory = NewPlayerAsAthena->GetWorldInventory(); - auto GameState = ((AFortGameModeAthena*)GameMode)->GetGameStateAthena(); - auto PlayerStateAthena = NewPlayerAsAthena->GetPlayerStateAthena(); - - if (!PlayerStateAthena) - return nullptr; + if (!WorldInventory) + return NewPawn; - auto ASC = PlayerStateAthena->GetAbilitySystemComponent(); - - GET_PLAYLIST(GameState); - - if (CurrentPlaylist) // Apply gameplay effects from playlist // We need to move this! + if (!WorldInventory->GetPickaxeInstance()) { - CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena); - } + // TODO Check Playlist->bRequirePickaxeInStartingInventory - auto PlayerAbilitySet = GetPlayerAbilitySet(); // Apply default gameplay effects // We need to move maybe? + auto& StartingItems = ((AFortGameModeAthena*)GameMode)->GetStartingItems(); - if (PlayerAbilitySet && ASC) - { - PlayerAbilitySet->ApplyGrantedGameplayAffectsToAbilitySystem(ASC); - } + NewPlayerAsAthena->AddPickaxeToInventory(); - if (NewPlayerAsAthena) - { - auto WorldInventory = NewPlayerAsAthena->GetWorldInventory(); - - if (!WorldInventory) - return NewPawn; - - if (!WorldInventory->GetPickaxeInstance()) + for (int i = 0; i < StartingItems.Num(); i++) { - // TODO Check Playlist->bRequirePickaxeInStartingInventory + auto& StartingItem = StartingItems.at(i); - auto& StartingItems = ((AFortGameModeAthena*)GameMode)->GetStartingItems(); - - NewPlayerAsAthena->AddPickaxeToInventory(); - - for (int i = 0; i < StartingItems.Num(); i++) - { - auto& StartingItem = StartingItems.at(i); - - WorldInventory->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount()); - } - - /* if (Globals::bLateGame) - { - auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup"); - - for (int i = 0; i < 5; i++) - { - auto LootDrops = PickLootDrops(SpawnIslandTierGroup); - - for (auto& LootDrop : LootDrops) - { - WorldInventory->AddItem(LootDrop.ItemDefinition, nullptr, LootDrop.Count, LootDrop.LoadedAmmo); - } - } - } */ - - auto AddInventoryOverrideTeamLoadouts = [&](AFortAthenaMutator* Mutator) - { - if (auto InventoryOverride = Cast(Mutator)) - { - auto TeamIndex = PlayerStateAthena->GetTeamIndex(); - auto LoadoutTeam = InventoryOverride->GetLoadoutTeamForTeamIndex(TeamIndex); - - if (LoadoutTeam.UpdateOverrideType == EAthenaInventorySpawnOverride::Always) - { - auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex); - - for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++) - { - auto& ItemAndCount = LoadoutContainer.Loadout.at(i); - WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount()); - } - } - } - }; - - LoopMutators(AddInventoryOverrideTeamLoadouts); - - WorldInventory->Update(); + WorldInventory->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount()); } + + /* if (Globals::bLateGame) + { + auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup"); + + for (int i = 0; i < 5; i++) + { + auto LootDrops = PickLootDrops(SpawnIslandTierGroup); + + for (auto& LootDrop : LootDrops) + { + WorldInventory->AddItem(LootDrop.ItemDefinition, nullptr, LootDrop.Count, LootDrop.LoadedAmmo); + } + } + } */ + + auto AddInventoryOverrideTeamLoadouts = [&](AFortAthenaMutator* Mutator) + { + if (auto InventoryOverride = Cast(Mutator)) + { + auto TeamIndex = PlayerStateAthena->GetTeamIndex(); + auto LoadoutTeam = InventoryOverride->GetLoadoutTeamForTeamIndex(TeamIndex); + + if (LoadoutTeam.UpdateOverrideType == EAthenaInventorySpawnOverride::Always) + { + auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex); + + for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++) + { + auto& ItemAndCount = LoadoutContainer.Loadout.at(i); + WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount()); + } + } + } + }; + + LoopMutators(AddInventoryOverrideTeamLoadouts); + + WorldInventory->Update(); } } + else + { + auto DeathInfo = (void*)(__int64(PlayerStateAthena) + MemberOffsets::FortPlayerStateAthena::DeathInfo); + + static auto DeathInfoStruct = FindObject(L"/Script/FortniteGame.DeathInfo"); + static auto DeathInfoStructSize = DeathInfoStruct->GetPropertiesSize(); + RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize); + } return NewPawn; } \ No newline at end of file diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index e98ff82..ba3d29b 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -546,27 +546,17 @@ std::vector Addresses::GetFunctionsToNull() toNull.push_back(Memcury::Scanner::FindPattern("40 55 57 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 0F B6 FA 44 8B F9 74 3B 80 3D ? ? ? ? ? 0F").Get()); } - if (std::floor(Fortnite_Version) == 16) - { - toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A F8 4C 8B F2 48").Get()); // no reservation in gakme - } - - if (std::floor(Fortnite_Version) == 17) - { - // toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 70 08 48 89 78 10 55 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 ED").Get()); // collectgarbage - } - - if (Fortnite_Version == 17.50) - { - toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A").Get()); // no reservation in game - } - if (Engine_Version == 500) { // toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 F6 0F 29 70 A8 44 38 35").Get()); // zone toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 55 56 57 41 54 41 55 41 56 41 57 48 8D 68 A8 48 81 EC ? ? ? ? 45").Get()); // GC } + if (Engine_Version >= 426) + { + toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A").Get()); // No reserve + } + toNull.push_back(Addresses::ChangeGameSessionId); return toNull; diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index ceaa341..a42cdea 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -183,7 +183,7 @@ DWORD WINAPI Main(LPVOID) static auto FortKismetLibraryDefault = FindObject(L"/Script/FortniteGame.Default__FortKismetLibrary"); static auto AthenaMarkerComponentDefault = FindObject(L"/Script/FortniteGame.Default__AthenaMarkerComponent"); static auto FortWeaponDefault = FindObject(L"/Script/FortniteGame.Default__FortWeapon"); - static auto FortOctopusVehicleDefault = FindObject("/Script/FortniteGame.Default__FortOctopusVehicle"); + static auto FortOctopusVehicleDefault = FindObject(L"/Script/FortniteGame.Default__FortOctopusVehicle"); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetPackageMap VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetTraffic VeryVerbose", nullptr); @@ -546,7 +546,7 @@ DWORD WINAPI Main(LPVOID) AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false); Hooking::MinHook::Hook((PVOID)GetFunctionIdxOrPtr(FindObject(L"/Script/FortniteGame.FortPlayerPawn.ServerOnExitVehicle"), true), AFortPlayerPawn::ServerOnExitVehicleHook, (PVOID*)&AFortPlayerPawn::ServerOnExitVehicleOriginal); - static auto FortGameplayAbilityAthena_PeriodicItemGrantDefault = FindObject("/Script/FortniteGame.Default__FortGameplayAbilityAthena_PeriodicItemGrant"); + static auto FortGameplayAbilityAthena_PeriodicItemGrantDefault = FindObject(L"/Script/FortniteGame.Default__FortGameplayAbilityAthena_PeriodicItemGrant"); if (FortGameplayAbilityAthena_PeriodicItemGrantDefault) { @@ -650,7 +650,7 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(InventoryManagementLibraryDefault, FindObject(L"/Script/FortniteGame.InventoryManagementLibrary.SwapItems"), UInventoryManagementLibrary::SwapItemsHook, (PVOID*)&UInventoryManagementLibrary::SwapItemsOriginal, false, true); - Hooking::MinHook::Hook(FindObject("/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"), + Hooking::MinHook::Hook(FindObject(L"/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"), AFortAthenaVehicleSpawner::SpawnVehicleHook, nullptr, false); static auto ServerHandlePickupInfoFn = FindObject(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo"); @@ -785,7 +785,7 @@ DWORD WINAPI Main(LPVOID) LOG_INFO(LogDev, "PredictionKeySize: 0x{:x} {}", PredictionKeySize, PredictionKeySize); - static auto GameplayEventDataSize = FindObject("/Script/GameplayAbilities.GameplayEventData")->GetPropertiesSize(); + static auto GameplayEventDataSize = FindObject(L"/Script/GameplayAbilities.GameplayEventData")->GetPropertiesSize(); LOG_INFO(LogDev, "GameplayEventDataSize: 0x{:x} {}", GameplayEventDataSize, GameplayEventDataSize); { diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index cdcd8c9..cb44fb0 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -144,6 +144,8 @@ static inline uint64 FindObjectArray() static inline uint64 FindPickupInitialize() { + if (Engine_Version == 419) + return Memcury::Scanner::FindPattern("48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 41 0F B6 E9").Get(); // 1.11 if (Engine_Version == 420) return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 41 56 48 83 EC 20 80 B9 ? ? ? ? ? 45 0F B6 F1 49 8B E8").Get(); // 4.1 if (Engine_Version == 421)