From 3b0f0ad4e1129fd14d70d8175a9a39de45ca303a Mon Sep 17 00:00:00 2001 From: Milxnor Date: Mon, 1 May 2023 23:52:41 -0400 Subject: [PATCH] cool update add option for auto restart, fix some bugs with auto restart, fix a crash with having no playlist set, fix double pleasant and hlod buildings on 7.30, fix 6.21 hlod buildings, performance --- Project Reboot 3.0/FortGameModeAthena.cpp | 102 ++++++++++++++------ Project Reboot 3.0/FortLootPackage.cpp | 2 +- Project Reboot 3.0/FortPlayerController.cpp | 72 +++++++------- Project Reboot 3.0/World.cpp | 19 ++-- Project Reboot 3.0/globals.h | 2 +- Project Reboot 3.0/gui.h | 6 +- Project Reboot 3.0/vendingmachine.h | 17 +++- 7 files changed, 140 insertions(+), 80 deletions(-) diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 2c2bc4b..f61f229 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -33,6 +33,8 @@ static UFortPlaylist* GetPlaylistToUse() { + // LOG_DEBUG(LogDev, "PlaylistName: {}", PlaylistName); + auto Playlist = FindObject(PlaylistName); if (Globals::bGoingToPlayEvent) @@ -202,7 +204,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game LOG_INFO(LogDev, "Presetup!"); - GameMode->Get("WarmupRequiredPlayerCount") = 1; + static auto WarmupRequiredPlayerCountOffset = GameMode->GetOffset("WarmupRequiredPlayerCount"); + GameMode->Get(WarmupRequiredPlayerCountOffset) = 1; static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false); @@ -238,22 +241,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { if (Fortnite_Season == 7) { - if (Fortnite_Version == 7.30) - { - // should be automatic.. - - if (true) - { - auto PleasantParkIdk = FindObject(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus")); - ShowFoundation(PleasantParkIdk); - } - else - { - auto PleasantParkGround = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault"); - ShowFoundation(PleasantParkGround); - } - } - ShowFoundation(FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_Athena_POI_25x36")); // Polar Peak ShowFoundation(FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.ShopsNew")); // Tilted Tower Shops, is this 7.40 specific? } @@ -353,11 +340,16 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (Fortnite_Version == 7.30) { - auto PleasantParkIdk = FindObject(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus")); - ShowFoundation(PleasantParkIdk); - - auto PleasantParkGround = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault"); - ShowFoundation(PleasantParkGround); + if (true) // idfk if the stage only showed on marshmello playlist + { + auto PleasantParkIdk = FindObject(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus")); + ShowFoundation(PleasantParkIdk); + } + else + { + auto PleasantParkGround = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault"); + ShowFoundation(PleasantParkGround); + } } if (Fortnite_Season == 6) @@ -368,7 +360,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game auto Lake2 = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_Lake2"); Fortnite_Version <= 6.21 ? ShowFoundation(Lake) : ShowFoundation(Lake2); - // ^ This shows the lake after or before the event i dont know if this is needed. } else { @@ -424,7 +415,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } } - SetBitfield(GameMode->GetPtr("bWorldIsReady"), 1, true); // idk when we actually set this + static auto bWorldIsReadyOffset = GameMode->GetOffset("bWorldIsReady"); + SetBitfield(GameMode->GetPtr(bWorldIsReadyOffset), 1, true); // idk when we actually set this // Calendar::SetSnow(1000); @@ -465,8 +457,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game // if (!Globals::bCreative) { - static auto FortPlayerStartWarmupClass = Globals::bCreative ? FindObject("/Script/FortniteGame.FortPlayerStartCreative") : FindObject("/Script/FortniteGame.FortPlayerStartWarmup"); - TArray Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortPlayerStartWarmupClass); + static auto FortPlayerStartCreativeClass = FindObject("/Script/FortniteGame.FortPlayerStartCreative"); + static auto FortPlayerStartWarmupClass = FindObject("/Script/FortniteGame.FortPlayerStartWarmup"); + TArray Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), Globals::bCreative ? FortPlayerStartCreativeClass : FortPlayerStartWarmupClass); int ActorsNum = Actors.Num(); @@ -499,11 +492,16 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode)); - GameState->Get("WarmupCountdownEndTime") = TimeSeconds + Duration; - GameMode->Get("WarmupCountdownDuration") = Duration; + static auto WarmupCountdownEndTimeOffset = GameState->GetOffset("WarmupCountdownEndTime"); + static auto WarmupCountdownStartTimeOffset = GameState->GetOffset("WarmupCountdownStartTime"); + static auto WarmupCountdownDurationOffset = GameMode->GetOffset("WarmupCountdownDuration"); + static auto WarmupEarlyCountdownDurationOffset = GameMode->GetOffset("WarmupEarlyCountdownDuration"); - GameState->Get("WarmupCountdownStartTime") = TimeSeconds; - GameMode->Get("WarmupEarlyCountdownDuration") = EarlyDuration; + GameState->Get(WarmupCountdownEndTimeOffset) = TimeSeconds + Duration; + GameMode->Get(WarmupCountdownDurationOffset) = Duration; + + GameState->Get(WarmupCountdownStartTimeOffset) = TimeSeconds; + GameMode->Get(WarmupEarlyCountdownDurationOffset) = EarlyDuration; static auto GameSessionOffset = GameMode->GetOffset("GameSession"); auto GameSession = GameMode->Get(GameSessionOffset); @@ -583,6 +581,50 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } } + std::vector WorldNamesToStreamAllFoundationsIn; // wtf + + if (Fortnite_Version == 6.21) + { + WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_Lake_002_5d9a86c8.Athena_POI_Lake_002:PersistentLevel."); + } + + if (Fortnite_Version == 7.30) + { + // idk what one we actually need + WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_CommunityPark_003_77acf920"); + WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_CommunityPark_003_M_5c711338"); + } + + if (WorldNamesToStreamAllFoundationsIn.size() > 0) + { + auto ObjectNum = ChunkedObjects ? ChunkedObjects->Num() : UnchunkedObjects ? UnchunkedObjects->Num() : 0; + + for (int i = 0; i < ObjectNum; i++) + { + auto CurrentObject = GetObjectByIndex(i); + + if (!CurrentObject) + continue; + + static auto BuildingFoundationClass = FindObject("/Script/FortniteGame.BuildingFoundation"); + + if (!CurrentObject->IsA(BuildingFoundationClass)) + continue; + + auto CurrentObjectFullName = CurrentObject->GetFullName(); // We can do GetPathName() and starts with but eh. + + for (int z = 0; z < WorldNamesToStreamAllFoundationsIn.size(); z++) + { + if (CurrentObject->GetFullName().contains(WorldNamesToStreamAllFoundationsIn.at(z))) + { + // I think we only have to set bServerStreamedInLevel. + ShowFoundation((AActor*)CurrentObject); + continue; + } + } + } + } + Globals::bStartedListening = true; } diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index 1f8d143..e3fdda4 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -583,7 +583,7 @@ std::vector PickLootDrops(FName TierGroupName, bool bPrint, int recurs if (bPrint) { - LOG_INFO(LogDev, "Adding LootPackage: {}", CurrentLP->GetAnnotation().ToString()); + // LOG_INFO(LogDev, "Adding LootPackage: {}", CurrentLP->GetAnnotation().ToString()); } } } diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index e65e806..d336f35 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -1235,50 +1235,51 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo { auto WorldInventory = PlayerController->GetWorldInventory(); - if (!WorldInventory) - return ClientOnPawnDiedOriginal(PlayerController, DeathReport); - - auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances(); - - std::vector> GuidAndCountsToRemove; - - for (int i = 0; i < ItemInstances.Num(); i++) + if (WorldInventory) { - auto ItemInstance = ItemInstances.at(i); - // LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance)); + auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances(); - if (!ItemInstance) - continue; + std::vector> GuidAndCountsToRemove; - auto ItemEntry = ItemInstance->GetItemEntry(); - auto WorldItemDefinition = Cast(ItemEntry->GetItemDefinition()); + for (int i = 0; i < ItemInstances.Num(); i++) + { + auto ItemInstance = ItemInstances.at(i); - // LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject"); + // LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance)); - if (!WorldItemDefinition) - continue; + if (!ItemInstance) + continue; - auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath(); + auto ItemEntry = ItemInstance->GetItemEntry(); + auto WorldItemDefinition = Cast(ItemEntry->GetItemDefinition()); - // LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped); + // LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject"); - if (!ShouldBeDropped) - continue; + if (!WorldItemDefinition) + continue; - AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination, - ItemEntry->GetLoadedAmmo()); + auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath(); - GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() }); - // WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount()); + // LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped); + + if (!ShouldBeDropped) + continue; + + AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination, + ItemEntry->GetLoadedAmmo()); + + GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() }); + // WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount()); + } + + for (auto& Pair : GuidAndCountsToRemove) + { + WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true); + } + + WorldInventory->Update(); } - - for (auto& Pair : GuidAndCountsToRemove) - { - WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true); - } - - WorldInventory->Update(); } auto GameMode = Cast(GetWorld()->GetGameMode()); @@ -1354,13 +1355,16 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo } // LOG_INFO(LogDev, "KillerPlayerState->Place: {}", KillerPlayerState ? KillerPlayerState->GetPlace() : -1); + } - bool bDidSomeoneWin = false; - + if (IsRestartingSupported() && Globals::bAutoRestart && !bIsInAutoRestart) + { // wtf auto AllPlayerStates = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortPlayerStateAthena::StaticClass()); + bool bDidSomeoneWin = AllPlayerStates.Num() == 0; + for (int i = 0; i < AllPlayerStates.Num(); i++) { if (((AFortPlayerStateAthena*)AllPlayerStates.at(i))->GetPlace() <= 1) diff --git a/Project Reboot 3.0/World.cpp b/Project Reboot 3.0/World.cpp index e707413..106085d 100644 --- a/Project Reboot 3.0/World.cpp +++ b/Project Reboot 3.0/World.cpp @@ -37,12 +37,14 @@ void UWorld::Listen() static bool (*InitHost)(UObject* Beacon) = decltype(InitHost)(Addresses::InitHost); static void (*PauseBeaconRequests)(UObject* Beacon, bool bPause) = decltype(PauseBeaconRequests)(Addresses::PauseBeaconRequests); - NewBeacon->Get("ListenPort") = Engine_Version < 426 ? Port - 1 : Port; + static auto ListenPortOffset = NewBeacon->GetOffset("ListenPort"); + NewBeacon->Get(ListenPortOffset) = Engine_Version < 426 ? Port - 1 : Port; InitHost(NewBeacon); PauseBeaconRequests(NewBeacon, false); - NewNetDriver = NewBeacon->Get("NetDriver"); + static auto Beacon_NetDriverOffset = NewBeacon->GetOffset("NetDriver"); + NewNetDriver = NewBeacon->Get(Beacon_NetDriverOffset); } else { @@ -55,8 +57,11 @@ void UWorld::Listen() return; } - NewNetDriver->Get("NetDriverName") = GameNetDriverName; - GetWorld()->Get("NetDriver") = NewNetDriver; + static auto NetDriverNameOffset = NewNetDriver->GetOffset("NetDriverName"); + NewNetDriver->Get(NetDriverNameOffset) = GameNetDriverName; + + static auto World_NetDriverOffset = GetWorld()->GetOffset("NetDriver"); + GetWorld()->Get(World_NetDriverOffset) = NewNetDriver; FURL URL = FURL(); URL.Port = Port - (Engine_Version >= 426); @@ -73,8 +78,9 @@ void UWorld::Listen() // LEVEL COLLECTIONS - auto& LevelCollections = GetWorld()->Get>("LevelCollections"); - int LevelCollectionSize = FindObject("/Script/Engine.LevelCollection")->GetPropertiesSize(); + static auto LevelCollectionsOffset = GetWorld()->GetOffset("LevelCollections"); + auto& LevelCollections = GetWorld()->Get>(LevelCollectionsOffset); + static int LevelCollectionSize = FindObject("/Script/Engine.LevelCollection")->GetPropertiesSize(); *(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = NewNetDriver; *(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = NewNetDriver; @@ -87,6 +93,7 @@ AWorldSettings* UWorld::GetWorldSettings(const bool bCheckStreamingPersistent, c // checkSlow(!IsInActualRenderingThread()); AWorldSettings* WorldSettings = nullptr; static auto PersistentLevelOffset = GetOffset("PersistentLevel"); + if (Get(PersistentLevelOffset)) { WorldSettings = Get(PersistentLevelOffset)->GetWorldSettings(bChecked); diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h index 92300f3..171c79c 100644 --- a/Project Reboot 3.0/globals.h +++ b/Project Reboot 3.0/globals.h @@ -8,7 +8,7 @@ namespace Globals { extern inline bool bCreative = false; extern inline bool bGoingToPlayEvent = false; - extern inline bool bEnableAGIDs = false; + extern inline bool bEnableAGIDs = true; extern inline bool bNoMCP = true; extern inline bool bLogProcessEvent = false; // extern inline bool bLateGame = false; diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index 76976f3..2957309 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -58,7 +58,7 @@ static inline int SecondsUntilTravel = 5; static inline bool bSwitchedInitialLevel = false; -static inline bool bIsInAutoRestart = false; +extern inline bool bIsInAutoRestart = false; // THE BASE CODE IS FROM IMGUI GITHUB @@ -72,7 +72,7 @@ static inline void CleanupDeviceD3D(); static inline void ResetDevice(); static inline LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -static inline bool bStartedBus = false; +extern inline bool bStartedBus = false; static inline void Restart() // todo move? { @@ -263,7 +263,7 @@ static inline void StaticUI() { if (IsRestartingSupported()) { - // ImGui::Checkbox("Auto Restart", &Globals::bAutoRestart); + ImGui::Checkbox("Auto Restart", &Globals::bAutoRestart); } #ifndef PROD diff --git a/Project Reboot 3.0/vendingmachine.h b/Project Reboot 3.0/vendingmachine.h index 1efce80..aac8a00 100644 --- a/Project Reboot 3.0/vendingmachine.h +++ b/Project Reboot 3.0/vendingmachine.h @@ -63,11 +63,15 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector, static auto ItemCollectionsOffset = ItemCollector->GetOffset("ItemCollections"); auto& ItemCollections = ItemCollector->Get>(ItemCollectionsOffset); - auto CurrentPlaylist = GameState->GetCurrentPlaylist(); UCurveTable* FortGameData = nullptr; - static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData"); - FortGameData = CurrentPlaylist ? CurrentPlaylist->Get>(GameDataOffset).Get() : nullptr; + auto CurrentPlaylist = GameState->GetCurrentPlaylist(); + + if (CurrentPlaylist) + { + static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData"); + FortGameData = CurrentPlaylist ? CurrentPlaylist->GetPtr>(GameDataOffset)->Get() : nullptr; + } if (!FortGameData) FortGameData = FindObject("/Game/Athena/Balance/AthenaGameData.AthenaGameData"); // uhm so theres one without athena and on newer versions that has it so idk @@ -187,8 +191,11 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector, } // The reason I set the curve to 0 is because it will force it to return value, probably not how we are supposed to do it but whatever. - ItemCollection->GetInputCount()->GetCurve().CurveTable = Fortnite_Version < 5 ? nullptr : FortGameData; // scuffed idc - ItemCollection->GetInputCount()->GetCurve().RowName = Fortnite_Version < 5 ? FName(0) : WoodName; // Scuffed idc + + bool bShouldBeNullTable = true; // Fortnite_Version < 5 + + ItemCollection->GetInputCount()->GetCurve().CurveTable = bShouldBeNullTable ? nullptr : FortGameData; // scuffed idc + ItemCollection->GetInputCount()->GetCurve().RowName = bShouldBeNullTable ? FName(0) : WoodName; // Scuffed idc ItemCollection->GetInputCount()->GetValue() = RarityToUse == 0 ? CommonPrice : RarityToUse == 1 ? UncommonPrice : RarityToUse == 2 ? RarePrice