diff --git a/Project Reboot 3.0/FortGadgetItemDefinition.cpp b/Project Reboot 3.0/FortGadgetItemDefinition.cpp index 6b97e35..dd79434 100644 --- a/Project Reboot 3.0/FortGadgetItemDefinition.cpp +++ b/Project Reboot 3.0/FortGadgetItemDefinition.cpp @@ -19,14 +19,4 @@ void UFortGadgetItemDefinition::UnequipGadgetData(AFortPlayerController* PlayerC ApplyCID(Cast(PlayerController->GetMyFortPawn()), CharacterToApply); // idk why no automatic } } -} - -void UFortGadgetItemDefinition::UpdateTrackedAttributesHook(UFortGadgetItemDefinition* GadgetItemDefinition) -{ - // LOG_INFO(LogDev, "UpdateTrackedAttributesHook Return: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); - - if (GadgetItemDefinition->ShouldDestroyGadgetWhenTrackedAttributesIsZero()) - { - // PlayerState->MulticastTriggerOnGadgetTrackedAttributeDestroyedFX - } } \ No newline at end of file diff --git a/Project Reboot 3.0/FortGadgetItemDefinition.h b/Project Reboot 3.0/FortGadgetItemDefinition.h index 1de6d6e..a663894 100644 --- a/Project Reboot 3.0/FortGadgetItemDefinition.h +++ b/Project Reboot 3.0/FortGadgetItemDefinition.h @@ -51,8 +51,6 @@ public: void UnequipGadgetData(AFortPlayerController* PlayerController, UFortItem* Item); - static void UpdateTrackedAttributesHook(UFortGadgetItemDefinition* GadgetItemDefinition); - static UClass* StaticClass() { static auto Class = FindObject("/Script/FortniteGame.FortGadgetItemDefinition"); diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index ef3d946..b864134 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -489,7 +489,19 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode)); - float Duration = 100000.f; + bool bShouldSkipAircraft = false; + + GET_PLAYLIST(GameState); + + if (CurrentPlaylist) + { + static auto bSkipAircraftOffset = CurrentPlaylist->GetOffset("bSkipAircraft", false); + + if (bSkipAircraftOffset != -1) + bShouldSkipAircraft = CurrentPlaylist->Get(bSkipAircraftOffset); + } + + float Duration = bShouldSkipAircraft ? 0 : 100000; float EarlyDuration = Duration; float TimeSeconds = UGameplayStatics::GetTimeSeconds(GetWorld()); @@ -522,8 +534,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (GameState_AirCraftBehaviorOffset != -1) { - GET_PLAYLIST(GameState); - if (CurrentPlaylist) { static auto Playlist_AirCraftBehaviorOffset = CurrentPlaylist->GetOffset("AirCraftBehavior", false); diff --git a/Project Reboot 3.0/FortGameStateAthena.cpp b/Project Reboot 3.0/FortGameStateAthena.cpp index 5040387..fa0e083 100644 --- a/Project Reboot 3.0/FortGameStateAthena.cpp +++ b/Project Reboot 3.0/FortGameStateAthena.cpp @@ -4,6 +4,7 @@ #include "FortPlayerStateAthena.h" #include "FortGameModeAthena.h" #include "FortAthenaMutator.h" +#include "gui.h" /* void AFortGameStateAthena::AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState) { @@ -257,6 +258,9 @@ void AFortGameStateAthena::OnRep_PlayersLeft() TeamsArrayContainer* AFortGameStateAthena::GetTeamsArrayContainer() { + if (!bEnableRebooting) // todo (milxnor) remove + return nullptr; + static auto FriendlyFireTypeOffset = GetOffset("FriendlyFireType"); static int Offset = -1; diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index 67b00c6..84d6598 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -13,8 +13,6 @@ struct FFortGameFeatureLootTableData TSoftObjectPtr LootPackageData; }; -#ifdef EXPERIMENTAL_LOOTING - template void CollectDataTablesRows(const std::vector& DataTables, std::map* OutMap, std::function Check = []() { return true; }) { @@ -24,7 +22,7 @@ void CollectDataTablesRows(const std::vector& DataTables, std::map< for (UDataTable* DataTable : DataTables) { - if (!DataTable->IsValidLowLevel()) + if (!Addresses::LoadAsset && !DataTable->IsValidLowLevel()) { continue; // Remove from vector? } @@ -368,18 +366,24 @@ std::vector PickLootDrops(FName TierGroupName, int ForcedLootTier, boo if (LootTierDataSoft.IsValid() && LootPackagesSoft.IsValid()) { -#ifndef brudda auto LootTierDataStr = LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); auto LootPackagesStr = LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); auto LootTierDataTableIsComposite = LootTierDataStr.contains("Composite"); auto LootPackageTableIsComposite = LootPackagesStr.contains("Composite"); - auto StrongLootTierData = LootTierDataSoft.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - auto StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); -#else - auto StrongLootTierData = (UDataTable*)Assets::LoadAsset(LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName); - auto StrongLootPackage = (UDataTable*)Assets::LoadAsset(LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName); -#endif + UDataTable* StrongLootTierData = nullptr; + UDataTable* StrongLootPackage = nullptr; + + if (!Addresses::LoadAsset) + { + StrongLootTierData = LootTierDataSoft.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); + StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); + } + else + { + StrongLootTierData = (UDataTable*)Assets::LoadAsset(LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName); + StrongLootPackage = (UDataTable*)Assets::LoadAsset(LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName); + } if (StrongLootTierData && StrongLootPackage) { @@ -393,19 +397,22 @@ std::vector PickLootDrops(FName TierGroupName, int ForcedLootTier, boo if (!bFoundPlaylistTable) { -#ifdef brudda - LTDTables.push_back((UDataTable*)Assets::LoadAsset(UKismetStringLibrary::Conv_StringToName(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"))); - LPTables.push_back((UDataTable*)Assets::LoadAsset(UKismetStringLibrary::Conv_StringToName(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client"))); -#else - LTDTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); - LPTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); -#endif + if (Addresses::LoadAsset) + { + LTDTables.push_back((UDataTable*)Assets::LoadAsset(UKismetStringLibrary::Conv_StringToName(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"))); + LPTables.push_back((UDataTable*)Assets::LoadAsset(UKismetStringLibrary::Conv_StringToName(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client"))); + } + else + { + LTDTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); + LPTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); + } } // LTDTables.push_back(LoadObject(L"/Game/Athena/Playlists/Playground/AthenaLootTierData_Client.AthenaLootTierData_Client")); // LPTables.push_back(LoadObject(L"/Game/Athena/Playlists/Playground/AthenaLootPackages_Client.AthenaLootPackages_Client")); - static auto FortGameFeatureDataClass = FindObject("/Script/FortniteGame.FortGameFeatureData"); + static auto FortGameFeatureDataClass = FindObject(L"/Script/FortniteGame.FortGameFeatureData"); if (FortGameFeatureDataClass) { @@ -573,48 +580,55 @@ std::vector PickLootDrops(FName TierGroupName, int ForcedLootTier, boo } } - if (Fortnite_Version <= 6 || std::floor(Fortnite_Version) == 9) // ahhh + if (!Addresses::LoadAsset) { - LTDTables.clear(); - LPTables.clear(); - - bool bFoundPlaylistTable = false; - - if (CurrentPlaylist) + if (Fortnite_Version <= 6 || std::floor(Fortnite_Version) == 9) // ahhh { - static auto LootTierDataOffset = CurrentPlaylist->GetOffset("LootTierData"); - auto& LootTierDataSoft = CurrentPlaylist->Get>(LootTierDataOffset); + LTDTables.clear(); + LPTables.clear(); - static auto LootPackagesOffset = CurrentPlaylist->GetOffset("LootPackages"); - auto& LootPackagesSoft = CurrentPlaylist->Get>(LootPackagesOffset); + bool bFoundPlaylistTable = false; - if (LootTierDataSoft.IsValid() && LootPackagesSoft.IsValid()) + if (CurrentPlaylist) { - auto LootTierDataStr = LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootPackagesStr = LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootTierDataTableIsComposite = LootTierDataStr.contains("Composite"); - auto LootPackageTableIsComposite = LootPackagesStr.contains("Composite"); + static auto LootTierDataOffset = CurrentPlaylist->GetOffset("LootTierData"); + auto& LootTierDataSoft = CurrentPlaylist->Get>(LootTierDataOffset); - auto StrongLootTierData = LootTierDataSoft.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - auto StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); + static auto LootPackagesOffset = CurrentPlaylist->GetOffset("LootPackages"); + auto& LootPackagesSoft = CurrentPlaylist->Get>(LootPackagesOffset); - if (StrongLootTierData && StrongLootPackage) + if (LootTierDataSoft.IsValid() && LootPackagesSoft.IsValid()) { - LTDTables.push_back(StrongLootTierData); - LPTables.push_back(StrongLootPackage); + auto LootTierDataStr = LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); + auto LootPackagesStr = LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); + auto LootTierDataTableIsComposite = LootTierDataStr.contains("Composite"); + auto LootPackageTableIsComposite = LootPackagesStr.contains("Composite"); - bFoundPlaylistTable = true; + UDataTable* StrongLootTierData = nullptr; + UDataTable* StrongLootPackage = nullptr; + + StrongLootTierData = LootTierDataSoft.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); + StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); + + if (StrongLootTierData && StrongLootPackage) + { + LTDTables.push_back(StrongLootTierData); + LPTables.push_back(StrongLootPackage); + + bFoundPlaylistTable = true; + } } } + + if (!bFoundPlaylistTable) + { + LTDTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); + LPTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); + } } - if (!bFoundPlaylistTable) - { - LTDTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); - LPTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); - } } - + if (LTDTables.size() <= 0 || LPTables.size() <= 0) { LOG_WARN(LogLoot, "Empty tables! ({} {})", LTDTables.size(), LPTables.size()); @@ -682,641 +696,4 @@ std::vector PickLootDrops(FName TierGroupName, int ForcedLootTier, boo } return LootDrops; -} -#else - -float GetRandomFloatForLooting(float min, float max) -{ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_real_distribution<> dis(min, max); - float random_number = dis(gen); - - return random_number; - - return UKismetMathLibrary::RandomFloatInRange(min, max); -} - -static FFortLootTierData* GetLootTierData(std::vector& LootTierData, float TotalWeight) -{ - FFortLootTierData* SelectedItem = nullptr; - - for (auto Item : LootTierData) - { - TotalWeight += Item->GetWeight(); - } - - float RandomNumber = GetRandomFloatForLooting(0, TotalWeight); // is -1 needed? - - for (auto Item : LootTierData) - { - if (RandomNumber <= Item->GetWeight()) - { - SelectedItem = Item; - break; - } - - RandomNumber -= Item->GetWeight(); - } - - if (!SelectedItem) - return GetLootTierData(LootTierData, TotalWeight); - - return SelectedItem; -} - -static FFortLootPackageData* GetLootPackage(std::vector& LootPackages, float TotalWeight) -{ - FFortLootPackageData* SelectedItem = nullptr; - - float RandomNumber = GetRandomFloatForLooting(0, TotalWeight); // is -1 needed? - - for (auto Item : LootPackages) - { - if (RandomNumber <= Item->GetWeight()) - { - SelectedItem = Item; - break; - } - - RandomNumber -= Item->GetWeight(); - } - - if (!SelectedItem) - return GetLootPackage(LootPackages, TotalWeight); - - return SelectedItem; -} - -std::vector PickLootDrops(FName TierGroupName, bool bPrint, int recursive) -{ - std::vector LootDrops; - - if (recursive > 6) - return LootDrops; - - auto GameState = ((AFortGameModeAthena*)GetWorld()->GetGameMode())->GetGameStateAthena(); - static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false); - - static std::vector LTDTables; - static std::vector LPTables; - - static auto CompositeDataTableClass = FindObject(L"/Script/Engine.CompositeDataTable"); - - static int LastNum1 = 14915; - - auto CurrentPlaylist = CurrentPlaylistDataOffset == -1 && Fortnite_Version < 6 ? nullptr : GameState->GetCurrentPlaylist(); - - if (LastNum1 != Globals::AmountOfListens) - { - LastNum1 = Globals::AmountOfListens; - - LTDTables.clear(); - LPTables.clear(); - - bool bFoundPlaylistTable = false; - - if (CurrentPlaylist) - { - static auto LootTierDataOffset = CurrentPlaylist->GetOffset("LootTierData"); - auto& LootTierDataSoft = CurrentPlaylist->Get>(LootTierDataOffset); - - static auto LootPackagesOffset = CurrentPlaylist->GetOffset("LootPackages"); - auto& LootPackagesSoft = CurrentPlaylist->Get>(LootPackagesOffset); - - if (LootTierDataSoft.IsValid() && LootPackagesSoft.IsValid()) - { - auto LootTierDataStr = LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootPackagesStr = LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootTierDataTableIsComposite = LootTierDataStr.contains("Composite"); - auto LootPackageTableIsComposite = LootPackagesStr.contains("Composite"); - - auto StrongLootTierData = LootTierDataSoft.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - auto StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - - if (StrongLootTierData && StrongLootPackage) - { - LTDTables.push_back(StrongLootTierData); - LPTables.push_back(StrongLootPackage); - - bFoundPlaylistTable = true; - } - } - } - - if (!bFoundPlaylistTable) - { - LTDTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); - LPTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); - } - - // LTDTables.push_back(LoadObject(L"/Game/Athena/Playlists/Playground/AthenaLootTierData_Client.AthenaLootTierData_Client")); - // LPTables.push_back(LoadObject(L"/Game/Athena/Playlists/Playground/AthenaLootPackages_Client.AthenaLootPackages_Client")); - - static auto FortGameFeatureDataClass = FindObject("/Script/FortniteGame.FortGameFeatureData"); - - if (FortGameFeatureDataClass) - { - for (int i = 0; i < ChunkedObjects->Num(); i++) - { - auto Object = ChunkedObjects->GetObjectByIndex(i); - - if (!Object) - continue; - - if (Object->IsA(FortGameFeatureDataClass)) - { - auto GameFeatureData = Object; - static auto DefaultLootTableDataOffset = GameFeatureData->GetOffset("DefaultLootTableData"); - - if (DefaultLootTableDataOffset != -1) - { - auto DefaultLootTableData = GameFeatureData->GetPtr(DefaultLootTableDataOffset); - - auto LootTierDataTableStr = DefaultLootTableData->LootTierData.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - - auto LootTierDataTableIsComposite = LootTierDataTableStr.contains("Composite"); - auto LootPackageTableStr = DefaultLootTableData->LootPackageData.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootPackageTableIsComposite = LootPackageTableStr.contains("Composite"); - - auto LootTierDataPtr = DefaultLootTableData->LootTierData.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - auto LootPackagePtr = DefaultLootTableData->LootPackageData.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - - if (LootPackagePtr) - { - LPTables.push_back(LootPackagePtr); - } - - if (CurrentPlaylist) - { - static auto PlaylistOverrideLootTableDataOffset = GameFeatureData->GetOffset("PlaylistOverrideLootTableData"); - auto& PlaylistOverrideLootTableData = GameFeatureData->Get>(PlaylistOverrideLootTableDataOffset); - - static auto GameplayTagContainerOffset = CurrentPlaylist->GetOffset("GameplayTagContainer"); - auto GameplayTagContainer = CurrentPlaylist->GetPtr(GameplayTagContainerOffset); - - for (int i = 0; i < GameplayTagContainer->GameplayTags.Num(); i++) - { - auto& Tag = GameplayTagContainer->GameplayTags.At(i); - - for (auto& Value : PlaylistOverrideLootTableData) - { - auto CurrentOverrideTag = Value.First; - - if (Tag.TagName == CurrentOverrideTag.TagName) - { - auto OverrideLootPackageTableStr = Value.Second.LootPackageData.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto bOverrideIsComposite = OverrideLootPackageTableStr.contains("Composite"); - - auto ptr = Value.Second.LootPackageData.Get(bOverrideIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - - if (ptr) - { - /* if (bOverrideIsComposite) - { - static auto ParentTablesOffset = ptr->GetOffset("ParentTables"); - - auto ParentTables = ptr->GetPtr>(ParentTablesOffset); - - for (int z = 0; z < ParentTables->size(); z++) - { - auto ParentTable = ParentTables->At(z); - - if (ParentTable) - { - LPTables.push_back(ParentTable); - } - } - } */ - - LPTables.push_back(ptr); - } - } - } - } - } - - if (LootTierDataPtr) - { - LTDTables.push_back(LootTierDataPtr); - } - - if (CurrentPlaylist) - { - static auto PlaylistOverrideLootTableDataOffset = GameFeatureData->GetOffset("PlaylistOverrideLootTableData"); - auto& PlaylistOverrideLootTableData = GameFeatureData->Get>(PlaylistOverrideLootTableDataOffset); - - static auto GameplayTagContainerOffset = CurrentPlaylist->GetOffset("GameplayTagContainer"); - auto GameplayTagContainer = CurrentPlaylist->GetPtr(GameplayTagContainerOffset); - - for (int i = 0; i < GameplayTagContainer->GameplayTags.Num(); i++) - { - auto& Tag = GameplayTagContainer->GameplayTags.At(i); - - for (auto& Value : PlaylistOverrideLootTableData) - { - auto CurrentOverrideTag = Value.First; - - if (Tag.TagName == CurrentOverrideTag.TagName) - { - auto OverrideLootTierDataStr = Value.Second.LootTierData.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto bOverrideIsComposite = OverrideLootTierDataStr.contains("Composite"); - - auto ptr = Value.Second.LootTierData.Get(bOverrideIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - - if (ptr) - { - /* if (bOverrideIsComposite) - { - static auto ParentTablesOffset = ptr->GetOffset("ParentTables"); - - auto ParentTables = ptr->GetPtr>(ParentTablesOffset); - - for (int z = 0; z < ParentTables->size(); z++) - { - auto ParentTable = ParentTables->At(z); - - if (ParentTable) - { - LTDTables.push_back(ParentTable); - } - } - } */ - - LTDTables.push_back(ptr); - } - } - } - } - } - } - } - } - } - - for (int i = 0; i < LTDTables.size(); i++) - { - auto& Table = LTDTables.at(i); - - if (!Table->IsValidLowLevel()) - { - continue; - } - - Table->AddToRoot(); - LOG_INFO(LogDev, "[{}] LTD {}", i, Table->GetFullName()); - } - - for (int i = 0; i < LPTables.size(); i++) - { - auto& Table = LPTables.at(i); - - if (!Table->IsValidLowLevel()) - { - continue; - } - - Table->AddToRoot(); - LOG_INFO(LogDev, "[{}] LP {}", i, Table->GetFullName()); - } - } - - if (Fortnite_Version <= 6 || std::floor(Fortnite_Version) == 9) // ahhh - { - LTDTables.clear(); - LPTables.clear(); - - bool bFoundPlaylistTable = false; - - if (CurrentPlaylist) - { - static auto LootTierDataOffset = CurrentPlaylist->GetOffset("LootTierData"); - auto& LootTierDataSoft = CurrentPlaylist->Get>(LootTierDataOffset); - - static auto LootPackagesOffset = CurrentPlaylist->GetOffset("LootPackages"); - auto& LootPackagesSoft = CurrentPlaylist->Get>(LootPackagesOffset); - - if (LootTierDataSoft.IsValid() && LootPackagesSoft.IsValid()) - { - auto LootTierDataStr = LootTierDataSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootPackagesStr = LootPackagesSoft.SoftObjectPtr.ObjectID.AssetPathName.ToString(); - auto LootTierDataTableIsComposite = LootTierDataStr.contains("Composite"); - auto LootPackageTableIsComposite = LootPackagesStr.contains("Composite"); - - auto StrongLootTierData = LootTierDataSoft.Get(LootTierDataTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - auto StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true); - - if (StrongLootTierData && StrongLootPackage) - { - LTDTables.push_back(StrongLootTierData); - LPTables.push_back(StrongLootPackage); - - bFoundPlaylistTable = true; - } - } - } - - if (!bFoundPlaylistTable) - { - LTDTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); - LPTables.push_back(LoadObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); - } - } - - if (LTDTables.size() <= 0 || LPTables.size() <= 0) - { - LOG_WARN(LogLoot, "Empty tables! ({} {})", LTDTables.size(), LPTables.size()); - return LootDrops; - } - - std::vector TierGroupLTDs; - - float TotalTierGroupLTDsWeight = 0; - - for (int p = 0; p < LTDTables.size(); p++) - { - auto LTD = LTDTables[p]; - - // if (bPrint) - // LOG_INFO(LogLoot, "LTD: {}", !LTD->IsValidLowLevel() ? "BadRead" : LTD->GetFullName()); - - if (!LTD->IsValidLowLevel()) - { - // if (bPrint) - LOG_INFO(LogLoot, "BadRead!"); - - continue; - } - - auto& LTDRowMap = LTD->GetRowMap(); - - for (auto& CurrentLTD : LTDRowMap) - { - auto TierData = (FFortLootTierData*)CurrentLTD.Value(); - - if (IsBadReadPtr(TierData, 8)) // this shouldn't be needed - continue; - - if (TierGroupName == TierData->GetTierGroup() && TierData->GetWeight() != 0) - { - TotalTierGroupLTDsWeight += TierData->GetWeight(); - TierGroupLTDs.push_back(TierData); - } - } - } - - if (TierGroupLTDs.size() == 0) - { - LOG_WARN(LogLoot, "Failed to find any LTD for: {}", TierGroupName.ToString()); - return LootDrops; - } - - FFortLootTierData* ChosenRowLootTierData = GetLootTierData(TierGroupLTDs, TotalTierGroupLTDsWeight); - - if (!ChosenRowLootTierData) // Should NEVER happen - return LootDrops; - - if (ChosenRowLootTierData->GetNumLootPackageDrops() <= 0) - return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm - - auto& LootPackageCategoryMinArray = ChosenRowLootTierData->GetLootPackageCategoryMinArray(); - auto& LootPackageCategoryWeightArray = ChosenRowLootTierData->GetLootPackageCategoryWeightArray(); - auto& LootPackageCategoryMaxArray = ChosenRowLootTierData->GetLootPackageCategoryMaxArray(); - - if (LootPackageCategoryMinArray.ArrayNum != LootPackageCategoryWeightArray.ArrayNum || - LootPackageCategoryMinArray.ArrayNum != LootPackageCategoryMaxArray.ArrayNum) - return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm - - int MinimumLootDrops = 0; - - static int AmountToAdd = Engine_Version >= 424 ? Engine_Version >= 500 ? 1 : 1 : 0; // fr - - float NumLootPackageDrops = std::floor(ChosenRowLootTierData->GetNumLootPackageDrops() + AmountToAdd); - - if (LootPackageCategoryMinArray.ArrayNum) - { - for (int i = 0; i < LootPackageCategoryMinArray.ArrayNum; i++) - { - if (LootPackageCategoryMinArray.at(i) > 0) - { - MinimumLootDrops += LootPackageCategoryMinArray.at(i); - } - } - } - - if (MinimumLootDrops > NumLootPackageDrops) - { - - } - - int SumLootPackageCategoryWeightArray = 0; - - for (int i = 0; i < LootPackageCategoryWeightArray.Num(); i++) - { - auto CategoryWeight = LootPackageCategoryWeightArray.at(i); - - if (CategoryWeight > 0) - { - auto CategoryMaxArray = LootPackageCategoryMaxArray.at(i); - - if (CategoryMaxArray < 0) - { - SumLootPackageCategoryWeightArray += CategoryWeight; - } - } - } - - int SumLootPackageCategoryMinArray = 0; - - for (int i = 0; i < LootPackageCategoryMinArray.Num(); i++) - { - auto CategoryWeight = LootPackageCategoryMinArray.at(i); - - if (CategoryWeight > 0) - { - auto CategoryMaxArray = LootPackageCategoryMaxArray.at(i); - - if (CategoryMaxArray < 0) - { - SumLootPackageCategoryMinArray += CategoryWeight; - } - } - } - - // if (SumLootPackageCategoryWeightArray > SumLootPackageCategoryMinArray) - // return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm - - std::vector TierGroupLPs; - - for (int p = 0; p < LPTables.size(); p++) - { - auto LP = LPTables[p]; - - if (!LP->IsValidLowLevel()) - continue; - - auto& LPRowMap = LP->GetRowMap(); - - for (auto& CurrentLP : LPRowMap) - { - auto LootPackage = (FFortLootPackageData*)CurrentLP.Value(); - - if (!LootPackage) - continue; - - if (LootPackage->GetLootPackageID() == ChosenRowLootTierData->GetLootPackage() && LootPackage->GetWeight() != 0 && LootPackage->GetCount() != 0) - { - TierGroupLPs.push_back(LootPackage); - } - } - } - - auto ChosenLootPackageName = ChosenRowLootTierData->GetLootPackage().ToString(); - - if (ChosenLootPackageName.contains(".Empty")) // I don't think? - { - return PickLootDrops(TierGroupName, bPrint, ++recursive); - // return LootDrops; - } - - bool bIsWorldList = ChosenLootPackageName.contains("WorldList"); - - if (bPrint) - { - LOG_INFO(LogLoot, "NumLootPackageDrops Floored: {}", NumLootPackageDrops); - LOG_INFO(LogLoot, "NumLootPackageDrops Original: {}", ChosenRowLootTierData->GetNumLootPackageDrops()); - LOG_INFO(LogLoot, "TierGroupLPs.size(): {}", TierGroupLPs.size()); - LOG_INFO(LogLoot, "ChosenLootPackageName: {}", ChosenLootPackageName); - - /* float t = ChosenRowLootTierData->NumLootPackageDrops; - - int b = (int)((t + t) - 0.5) >> 1; - auto c = ChosenRowLootTierData->NumLootPackageDrops - b; - - b += c >= (rand() * 0.000030518509); - - std::cout << "b: " << b << '\n'; */ - } - - LootDrops.reserve(NumLootPackageDrops); - - for (float i = 0; i < NumLootPackageDrops; i++) - { - FFortLootPackageData* TierGroupLP = nullptr; - - if (i >= TierGroupLPs.size()) - { - break; - /* auto randomNumberFloat = UKismetMathLibrary::RandomFloatInRange(0, TierGroupLPs.size()); - auto randomNumberFloored = std::floor((int)randomNumberFloat); // idk - - if (bPrint) - LOG_INFO(LogLoot, "randomNumberFloat: {} randomNumberFloored: {}", randomNumberFloat, randomNumberFloored); - - TierGroupLP = TierGroupLPs.at(randomNumberFloored); */ - - TierGroupLP = TierGroupLPs.at(i - NumLootPackageDrops); // Once we fix chapter 2 loot package drops, we can use this - } - else - { - TierGroupLP = TierGroupLPs.at(i); - } - - if (!TierGroupLP) - continue; - - auto& LootPackageCallFStr = TierGroupLP->GetLootPackageCall(); - auto TierGroupLPStr = LootPackageCallFStr.IsValid() ? LootPackageCallFStr.ToString() : "InvalidLootPackageCall.Empty"; - - if (bPrint) - LOG_INFO(LogLoot, "TierGroupLPStr: {}", TierGroupLPStr); - - if (!bIsWorldList && TierGroupLPStr.contains(".Empty")) - { - NumLootPackageDrops++; - continue; - } - - std::vector lootPackageCalls; - float lootPackageCallsTotalWeight = 0; - - if (bIsWorldList) - { - for (int j = 0; j < TierGroupLPs.size(); j++) - { - auto& CurrentLP = TierGroupLPs.at(j); - - if (CurrentLP->GetWeight() != 0) - { - lootPackageCallsTotalWeight += CurrentLP->GetWeight(); - lootPackageCalls.push_back(CurrentLP); - - if (bPrint) - { - // LOG_INFO(LogDev, "Adding LootPackage: {}", CurrentLP->GetAnnotation().ToString()); - } - } - } - } - else - { - for (int p = 0; p < LPTables.size(); p++) - { - if (!LPTables[p]->IsValidLowLevel()) - continue; - - auto& LPRowMap = LPTables[p]->GetRowMap(); - - for (auto& CurrentLP : LPRowMap) - { - auto LootPackage = (FFortLootPackageData*)CurrentLP.Value(); - - if (LootPackage->GetLootPackageID().ToString() == TierGroupLPStr && LootPackage->GetWeight() != 0 && LootPackage->GetCount() != 0) - { - lootPackageCallsTotalWeight += LootPackage->GetWeight(); - lootPackageCalls.push_back(LootPackage); - } - } - } - } - - if (bPrint) - LOG_INFO(LogLoot, "lootPackageCalls.size(): {}", lootPackageCalls.size()); - - if (lootPackageCalls.size() == 0) - { - // std::cout << "lootPackageCalls.size() == 0!\n"; - NumLootPackageDrops++; - continue; - } - - FFortLootPackageData* LootPackageCall = GetLootPackage(lootPackageCalls, lootPackageCallsTotalWeight); - - if (!LootPackageCall) // Should NEVER happen - { - LOG_ERROR(LogLoot, "Failed to get any loot package call??"); - NumLootPackageDrops++; - continue; - } - - auto ItemDef = LootPackageCall->GetItemDefinition().Get(UFortItemDefinition::StaticClass(), true); - - if (!ItemDef) - { - NumLootPackageDrops++; - continue; - } - - if (bPrint) - { - LOG_INFO(LogLoot, "[{}] {} {} {}", i, lootPackageCalls.size(), TierGroupLPStr, ItemDef->GetName()); - } - - auto WeaponDef = Cast(ItemDef); - - LootDrops.push_back(LootDrop(FFortItemEntry::MakeItemEntry(ItemDef, LootPackageCall->GetCount(), WeaponDef ? WeaponDef->GetClipSize() : 0)); - } - - return LootDrops; -} -#endif +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortLootPackage.h b/Project Reboot 3.0/FortLootPackage.h index 6e0d8df..667c63e 100644 --- a/Project Reboot 3.0/FortLootPackage.h +++ b/Project Reboot 3.0/FortLootPackage.h @@ -10,8 +10,6 @@ #include "SoftObjectPtr.h" #include "FortItem.h" -#define EXPERIMENTAL_LOOTING - struct FFortLootPackageData { public: diff --git a/Project Reboot 3.0/FortPickup.cpp b/Project Reboot 3.0/FortPickup.cpp index d20aa05..01a5e0f 100644 --- a/Project Reboot 3.0/FortPickup.cpp +++ b/Project Reboot 3.0/FortPickup.cpp @@ -32,7 +32,7 @@ void AFortPickup::SpawnMovementComponent() AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData) { if (PickupData.Source == -1) - PickupData.Source = 0; + PickupData.Source = -1; if (PickupData.SourceType == -1) PickupData.SourceType = -1; @@ -139,7 +139,7 @@ AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData) for (auto& AttributeValue : AttributeValueVector) { - // ReplicatedEntry->GetGenericAttributeValues().Add(AttributeValue); + PrimaryPickupItemEntry->GetGenericAttributeValues().Add(AttributeValue); } } } diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index a9b96c3..11670e9 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -10,6 +10,7 @@ #include "DataTableFunctionLibrary.h" #include "AthenaResurrectionComponent.h" #include "FortAthenaMutator_InventoryOverride.h" +#include "FortGadgetItemDefinition.h" void AFortPlayerControllerAthena::StartGhostModeHook(UObject* Context, FFrame* Stack, void* Ret) { @@ -500,4 +501,89 @@ void AFortPlayerControllerAthena::ServerReadyToStartMatchHook(AFortPlayerControl } return ServerReadyToStartMatchOriginal(PlayerController); +} + + +void AFortPlayerControllerAthena::UpdateTrackedAttributesHook(AFortPlayerControllerAthena* PlayerController) +{ + LOG_INFO(LogDev, "UpdateTrackedAttributesHook Return: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); + + // IDK IF GADGET IS A PARAM OR WHAT + + auto PlayerState = Cast(PlayerController->GetPlayerState()); // really we only need zone + + if (!PlayerState) + return; + + auto ASC = PlayerState->GetAbilitySystemComponent(); + + if (!ASC) + return; + + auto WorldInventory = PlayerController->GetWorldInventory(); + + if (!WorldInventory) + return; + + auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances(); + + std::vector ItemInstancesToRemove; + + for (int i = 0; i < ItemInstances.Num(); i++) + { + auto ItemInstance = ItemInstances.at(i); + auto GadgetItemDefinition = Cast(ItemInstance->GetItemEntry()->GetItemDefinition()); + + if (!GadgetItemDefinition) + continue; + + if (!GadgetItemDefinition->ShouldDestroyGadgetWhenTrackedAttributesIsZero()) + continue; + + bool bIsTrackedAttributesZero = true; + + for (int i = 0; i < GadgetItemDefinition->GetTrackedAttributes().Num(); i++) + { + auto& CurrentTrackedAttribute = GadgetItemDefinition->GetTrackedAttributes().at(i); + + int CurrentAttributeValue = -1; + + for (int i = 0; i < ASC->GetSpawnedAttributes().Num(); i++) + { + auto CurrentSpawnedAttribute = ASC->GetSpawnedAttributes().at(i); + + if (CurrentSpawnedAttribute->IsA(CurrentTrackedAttribute.AttributeOwner)) + { + auto PropertyOffset = CurrentSpawnedAttribute->GetOffset(CurrentTrackedAttribute.GetAttributePropertyName()); + + if (PropertyOffset != -1) + { + if (CurrentSpawnedAttribute->GetPtr(PropertyOffset)->GetCurrentValue() > 0) + { + bIsTrackedAttributesZero = false; + break; // hm + } + } + } + } + } + + if (bIsTrackedAttributesZero) + { + ItemInstancesToRemove.push_back(ItemInstance); + } + } + + for (auto ItemInstanceToRemove : ItemInstancesToRemove) + { + auto GadgetItemDefinition = Cast(ItemInstanceToRemove->GetItemEntry()->GetItemDefinition()); + + WorldInventory->RemoveItem(ItemInstanceToRemove->GetItemEntry()->GetItemGuid(), nullptr, ItemInstanceToRemove->GetItemEntry()->GetCount(), true); + + static auto MulticastTriggerOnGadgetTrackedAttributeDestroyedFXFn = FindObject(L"/Script/FortniteGame.FortPlayerStateZone.MulticastTriggerOnGadgetTrackedAttributeDestroyedFX"); + PlayerState->ProcessEvent(MulticastTriggerOnGadgetTrackedAttributeDestroyedFXFn, &GadgetItemDefinition); + } + + if (ItemInstancesToRemove.size() > 0) + WorldInventory->Update(); } \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index cad77c7..82c28e0 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -186,6 +186,7 @@ public: static void ServerPlaySquadQuickChatMessageHook(AFortPlayerControllerAthena* PlayerController, __int64 ChatEntry, __int64 SenderID); static void GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation); static void ServerReadyToStartMatchHook(AFortPlayerControllerAthena* PlayerController); + static void UpdateTrackedAttributesHook(AFortPlayerControllerAthena* PlayerController); static UClass* StaticClass() { diff --git a/Project Reboot 3.0/FortPlaylist.h b/Project Reboot 3.0/FortPlaylist.h index 55f05aa..77eaf7e 100644 --- a/Project Reboot 3.0/FortPlaylist.h +++ b/Project Reboot 3.0/FortPlaylist.h @@ -97,7 +97,7 @@ struct FFortGameplayEffectDeliveryInfo { static UStruct* GetStruct() { - static auto Struct = FindObject("/Script/FortniteGame.FortGameplayEffectDeliveryInfo"); + static auto Struct = FindObject(L"/Script/FortniteGame.FortGameplayEffectDeliveryInfo"); return Struct; } @@ -123,7 +123,7 @@ struct FFortAbilitySetDeliveryInfo { static UStruct* GetStruct() { - static auto Struct = FindObject("/Script/FortniteGame.FortAbilitySetDeliveryInfo"); + static auto Struct = FindObject(L"/Script/FortniteGame.FortAbilitySetDeliveryInfo"); return Struct; } @@ -165,6 +165,8 @@ public: if (!Actor) return; + // TODO Use the UAbilitySystemInterface or whatever + UAbilitySystemComponent* AbilitySystemComponent = nullptr; if (auto BuildingActor = Cast(Actor)) @@ -230,7 +232,7 @@ public: if (!CurrentGameplayEffect) continue; - LOG_INFO(LogDev, "Giving GameplayEffect {}", CurrentGameplayEffect->GetFullName()); + // LOG_INFO(LogDev, "Giving GameplayEffect {}", CurrentGameplayEffect->GetFullName()); AbilitySystemComponent->ApplyGameplayEffectToSelf(CurrentGameplayEffect, CurrentGameplayEffectInfo.Level); } } diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 4395dcd..471911e 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -562,6 +562,11 @@ 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) == 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 (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 diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index efbe598..25a107e 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -45,6 +45,16 @@ #include "FortAthenaVehicleSpawner.h" #include "FortGameSessionDedicatedAthena.h" +enum class EMeshNetworkNodeType : uint8_t +{ + Root = 0, + Inner = 1, + Edge = 2, + Client = 3, + Unknown = 4, + EMeshNetworkNodeType_MAX = 5 +}; + enum ENetMode { NM_Standalone, @@ -54,12 +64,19 @@ enum ENetMode NM_MAX, }; +static EMeshNetworkNodeType GetMeshNetworkNodeTypeHook(__int64 a1) +{ + LOG_INFO(LogDev, "GetMeshNetworkNodeTypeHook Ret: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); + return EMeshNetworkNodeType::Edge; +} + constexpr ENetMode NetMode = ENetMode::NM_DedicatedServer; static ENetMode GetNetModeHook() { return NetMode; } static ENetMode GetNetModeHook2() { return NetMode; } static bool ReturnTrueHook() { return true; } +static bool ReturnFalseHook() { return false; } static int Return2Hook() { return 2; } static bool NoMCPHook() { return Globals::bNoMCP; } @@ -134,6 +151,56 @@ void __fastcall ApplyHomebaseEffectsOnPlayerSetupHook( return ApplyHomebaseEffectsOnPlayerSetupOriginal(GameState, a2, a3, a4, Hero, a6, a7); } +/* + +static unsigned __int8 (*SpecialEventScript_ActivatePhaseOriginal)(UObject* SpecialEventScript, int NewPhase); + +unsigned __int8 SpecialEventScript_ActivatePhaseHook(UObject* SpecialEventScript, int NewPhase) +{ + LOG_INFO(LogDev, "SpecialEventScript_ActivatePhaseHook {}!", NewPhase); + + static auto ReplicatedActivePhaseIndexOffset = SpecialEventScript->GetOffset("ReplicatedActivePhaseIndex"); + SpecialEventScript->Get(ReplicatedActivePhaseIndexOffset) = NewPhase; + + static auto OnRep_ReplicatedActivePhaseIndexFn = FindObject("/Script/SpecialEventGameplayRuntime.SpecialEventScript.OnRep_ReplicatedActivePhaseIndex"); + SpecialEventScript->ProcessEvent(OnRep_ReplicatedActivePhaseIndexFn); + + return SpecialEventScript_ActivatePhaseOriginal(SpecialEventScript, NewPhase); +} + +*/ + +static void (*ActivatePhaseAtIndexOriginal)(UObject* SpecialEventScript, int Index); + +void ActivatePhaseAtIndexHook(UObject* SpecialEventScript, int Index) +{ + LOG_INFO(LogDev, "ActivatePhaseAtIndexHook {}!", Index); + + static auto ReplicatedActivePhaseIndexOffset = SpecialEventScript->GetOffset("ReplicatedActivePhaseIndex"); + SpecialEventScript->Get(ReplicatedActivePhaseIndexOffset) = Index; + + static auto OnRep_ReplicatedActivePhaseIndexFn = FindObject("/Script/SpecialEventGameplayRuntime.SpecialEventScript.OnRep_ReplicatedActivePhaseIndex"); + SpecialEventScript->ProcessEvent(OnRep_ReplicatedActivePhaseIndexFn); + + return ActivatePhaseAtIndexOriginal(SpecialEventScript, Index); +} + +static __int64 (*FlowStep_SetPhaseToActiveOriginal)(AActor* SpecialEventPhase); + +__int64 FlowStep_SetPhaseToActiveHook(AActor* SpecialEventPhase) +{ + LOG_INFO(LogDev, "FlowStep_SetPhaseToActiveHook!"); + + auto ret = FlowStep_SetPhaseToActiveOriginal(SpecialEventPhase); // idk if three actually is a ret + + static auto OnRep_PhaseState = FindObject("/Script/SpecialEventGameplayRuntime.SpecialEventPhase.OnRep_PhaseState"); + SpecialEventPhase->ProcessEvent(OnRep_PhaseState); + + SpecialEventPhase->ForceNetUpdate(); + + return ret; +} + DWORD WINAPI Main(LPVOID) { InitLogger(); @@ -179,6 +246,7 @@ DWORD WINAPI Main(LPVOID) static auto GameModeDefault = FindObject(L"/Script/FortniteGame.Default__FortGameModeAthena"); static auto FortPlayerControllerZoneDefault = FindObject(L"/Script/FortniteGame.Default__FortPlayerControllerZone"); + static auto FortPlayerControllerDefault = FindObject(L"/Script/FortniteGame.Default__FortPlayerController"); static auto FortPlayerControllerAthenaDefault = FindObject(L"/Script/FortniteGame.Default__FortPlayerControllerAthena"); // FindObject(L"/Game/Athena/Athena_PlayerController.Default__Athena_PlayerController_C"); static auto FortPlayerPawnAthenaDefault = FindObject(L"/Script/FortniteGame.Default__FortPlayerPawnAthena"); // FindObject(L"/Game/Athena/PlayerPawn_Athena.Default__PlayerPawn_Athena_C"); static auto FortAbilitySystemComponentAthenaDefault = FindObject(L"/Script/FortniteGame.Default__FortAbilitySystemComponentAthena"); @@ -196,10 +264,14 @@ DWORD WINAPI Main(LPVOID) // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortUIDirector NoLogging", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogDataTable VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogMeshNetwork VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFort VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogGameMode VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogSpecialEvent VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogPlayerController VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogSpecialEventPhase VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortCustomization VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogSpecialEventScriptMeshActor VeryVerbose", nullptr); Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr); Hooking::MinHook::Hook((PVOID)Addresses::GetNetMode, (PVOID)GetNetModeHook, nullptr); @@ -231,9 +303,27 @@ DWORD WINAPI Main(LPVOID) FindObject(L"/Script/FortniteGame.BuildingFoundation.SetDynamicFoundationEnabled"), ABuildingFoundation::SetDynamicFoundationEnabledHook, (PVOID*)&ABuildingFoundation::SetDynamicFoundationEnabledOriginal, false, true); */ + if (Fortnite_Version == 17.30) + { + // if (false) + { + Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E07910), (PVOID)GetMeshNetworkNodeTypeHook, nullptr); + // Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED12C), (PVOID)ReturnTrueHook, nullptr); // 7FF7E556D12C + Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED158), (PVOID)ReturnTrueHook, nullptr); // 7FF7E556D158 + } + + Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DECFC8), (PVOID)ReturnTrueHook, nullptr); // 7FF7E556CFC8 + Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED050), (PVOID)ReturnTrueHook, nullptr); // 7FF7E556D050 + Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DECF40), (PVOID)ReturnFalseHook, nullptr); // 7FF7E556CF40 + Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DE5CE8), (PVOID)ActivatePhaseAtIndexHook, (PVOID*)&ActivatePhaseAtIndexOriginal); // 7FF7E5565CE8 + // Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DE9268), (PVOID)FlowStep_SetPhaseToActiveHook, (PVOID*)&FlowStep_SetPhaseToActiveOriginal); // 7FF7E5569268 + // Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DE5998), (PVOID)SpecialEventScript_ActivatePhaseHook, (PVOID*)&SpecialEventScript_ActivatePhaseOriginal); // 7FF7E5565998 + } + 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" @@ -285,13 +375,6 @@ DWORD WINAPI Main(LPVOID) LOG_INFO(LogPlayer, "Switched level."); - if (Fortnite_Version == 17.30) - { - // Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E07910), (PVOID)Return2Hook, nullptr); - // Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED12C), (PVOID)ReturnTrueHook, nullptr); - Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED158), (PVOID)ReturnTrueHook, nullptr); - } - if (bUseSwitchLevel) { if (!bUseRemovePlayer) @@ -436,10 +519,15 @@ DWORD WINAPI Main(LPVOID) nullptr, false); } - // HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + static auto ServerReturnToMainMenuFn = FindObject(L"/Script/FortniteGame.FortPlayerController.ServerReturnToMainMenu"); + static auto ServerReturnToMainMenuIdx = GetFunctionIdxOrPtr(ServerReturnToMainMenuFn) / 8; + auto FortServerRestartPlayer = FortPlayerControllerDefault->VFTable[ServerReturnToMainMenuIdx]; + VirtualSwap(FortPlayerControllerAthenaDefault->VFTable, ServerReturnToMainMenuIdx, FortServerRestartPlayer); + + HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)AFortPlayerControllerAthena::UpdateTrackedAttributesHook, "/Script/Engine.PlayerController.EnableCheats", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); // HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); - if (false) + if (bEnableRebooting) { HookInstruction(Addresses::RebootingDelegate, (PVOID)ABuildingGameplayActorSpawnMachine::RebootingDelegateHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FindObject("/Script/FortniteGame.Default__BuildingGameplayActorSpawnMachine")); } diff --git a/Project Reboot 3.0/events.h b/Project Reboot 3.0/events.h index b840299..d2d696b 100644 --- a/Project Reboot 3.0/events.h +++ b/Project Reboot 3.0/events.h @@ -700,7 +700,7 @@ static inline void StartEvent() if (Fortnite_Version == 17.30) { - static bool (*IsServerOrSomething)(UObject * SpecialEventScript) = decltype(IsServerOrSomething)(__int64(GetModuleHandleW(0)) + 0x3DECFC8); + static bool (*IsServerOrSomething)(UObject* SpecialEventScript) = decltype(IsServerOrSomething)(__int64(GetModuleHandleW(0)) + 0x3DECFC8); LOG_INFO(LogDev, "IsServerOrSomething {}", IsServerOrSomething(EventScripting)); static auto OnRep_RootStartTimeFn = FindObject("/Script/SpecialEventGameplayRuntime.SpecialEventScriptMeshActor.OnRep_RootStartTime"); @@ -714,12 +714,16 @@ static inline void StartEvent() if (SpecialEventScriptMeshActor) { - static bool (*sub_7FF7E556D158)(UObject * MeshScriptActor) = decltype(sub_7FF7E556D158)(__int64(GetModuleHandleW(0)) + 0x3DED158); + static bool (*sub_7FF7E556D158)(UObject* MeshScriptActor) = decltype(sub_7FF7E556D158)(__int64(GetModuleHandleW(0)) + 0x3DED158); LOG_INFO(LogDev, "sub_7FF7E556D158 {}", sub_7FF7E556D158(SpecialEventScriptMeshActor)); - SpecialEventScriptMeshActor->ProcessEvent(MeshRootStartEventFn); - SpecialEventScriptMeshActor->ProcessEvent(OnRep_RootStartTimeFn); - return; + // if (false) + { + SpecialEventScriptMeshActor->ProcessEvent(MeshRootStartEventFn); + SpecialEventScriptMeshActor->ProcessEvent(OnRep_RootStartTimeFn); + + return; + } } else { diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 7f92426..e75daa3 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -186,9 +186,20 @@ static inline uint64 FindFinishResurrection() static inline uint64 FindGetSquadIdForCurrentPlayer() { - auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 40 48 8D 99 ? ? ? ? 48 8B FA 4C 8B C2 48 8B CB").Get(); + auto Addrr = Memcury::Scanner::FindStringRef(L"GetSquadIdForCurrentPlayer failed to find a squad id for player %s").Get(); - return addr; + if (!Addrr) + return 0; + + for (int i = 0; i < 2000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C) + { + return Addrr - i; + } + } + + return 0; } static inline uint64 FindRebootingDelegate() @@ -196,7 +207,21 @@ static inline uint64 FindRebootingDelegate() if (Fortnite_Version < 8.3) return 0; - auto addr = Memcury::Scanner::FindPattern("48 8D 05 ? ? ? ? 33 F6 48 89 44 24 ? 49 8B CE 49 8B 06 89 74 24 60 FF 90 ? ? ? ? 4C 8B A4 24 ? ? ? ? 48 8B 88 ? ? ? ? 48 85 C9").Get(); + auto ServerOnAttemptInteractAddr = Memcury::Scanner::FindStringRef(L"[SCM] ABuildingGameplayActorSpawnMachine::ServerOnAttemptInteract - Start Rebooting").Get(); + + for (int i = 0; i < 10000; i++) + { + if ((*(uint8_t*)(uint8_t*)(ServerOnAttemptInteractAddr + i) == 0x48 && *(uint8_t*)(uint8_t*)(ServerOnAttemptInteractAddr + i + 1) == 0x8D + && *(uint8_t*)(uint8_t*)(ServerOnAttemptInteractAddr + i + 2) == 0x05)) + { + auto loadAddress = Memcury::Scanner(ServerOnAttemptInteractAddr + i).RelativeOffset(3).Get(); + + if (IsNullSub(loadAddress)) // Safety + return ServerOnAttemptInteractAddr + i; + } + } + + auto addr = 0; // Memcury::Scanner::FindPattern("48 8D 05 ? ? ? ? 33 F6 48 89 44 24 ? 49 8B CE 49 8B 06 89 74 24 60 FF 90 ? ? ? ? 4C 8B A4 24 ? ? ? ? 48 8B 88 ? ? ? ? 48 85 C9").Get(); return addr; } @@ -231,6 +256,8 @@ static inline uint64 FindCreateNetDriver() static inline uint64 FindLoadAsset() { + return 0; + auto Addrr = Memcury::Scanner::FindStringRef(L"Loaded delay-load asset %s").Get(); for (int i = 0; i < 2000; i++) @@ -687,7 +714,7 @@ static inline uint64 FindUpdateTrackedAttributesLea() // kill me // So we keep going until we find a lea with nullsub.. - uint64 ApplyGadgetAttributesAddr = 0; + uint64 ApplyGadgetAttributesAddr = Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 55 41 54 41 55 41 57 48 8D 6C 24").Get(); if (!ApplyGadgetAttributesAddr) return 0; diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h index e037111..f418272 100644 --- a/Project Reboot 3.0/globals.h +++ b/Project Reboot 3.0/globals.h @@ -26,9 +26,9 @@ namespace Globals } extern inline std::string PlaylistName = -// "/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"; +"/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"; // "/Game/Athena/Playlists/gg/Playlist_Gg_Reverse.Playlist_Gg_Reverse"; -"/Game/Athena/Playlists/Playlist_DefaultDuo.Playlist_DefaultDuo"; +// "/Game/Athena/Playlists/Playlist_DefaultDuo.Playlist_DefaultDuo"; // "/Game/Athena/Playlists/Playground/Playlist_Playground.Playlist_Playground"; // "/Game/Athena/Playlists/Carmine/Playlist_Carmine.Playlist_Carmine"; // "/Game/Athena/Playlists/Fill/Playlist_Fill_Solo.Playlist_Fill_Solo"; diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index 7deb4f9..d6bdcee 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -284,7 +284,7 @@ static inline void StaticUI() #ifndef PROD ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent); - ImGui::InputInt("Amount of bots to spawn", &AmountOfBotsToSpawn); + // ImGui::InputInt("Amount of bots to spawn", &AmountOfBotsToSpawn); #endif ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo); diff --git a/Project Reboot 3.0/reboot.cpp b/Project Reboot 3.0/reboot.cpp index 9bcda9a..0f29bc7 100644 --- a/Project Reboot 3.0/reboot.cpp +++ b/Project Reboot 3.0/reboot.cpp @@ -6,7 +6,7 @@ UObject* Assets::LoadAsset(FName Name, bool ShowDelayTimes) { - static UObject* (*LoadAssetOriginal)(FName a1, bool a2); + static UObject* (*LoadAssetOriginal)(FName a1, bool a2) = decltype(LoadAssetOriginal)(Assets::LoadAsset); return LoadAssetOriginal(Name, ShowDelayTimes); } diff --git a/vendor/memcury.h b/vendor/memcury.h index 943f7b4..fa06cb9 100644 --- a/vendor/memcury.h +++ b/vendor/memcury.h @@ -1417,7 +1417,12 @@ // Finds a string ref, then goes searches xref of the function that it's in and returns that address. inline uintptr_t FindFunctionCall(const wchar_t* Name, const std::vector& Bytes = std::vector{ 0x48, 0x89, 0x5C }, int skip = 0) // credit ender & me { - auto FunctionPtr = Memcury::Scanner::FindStringRef(Name, true, skip).ScanFor({ 0x48, 0x8D, 0x0D }).RelativeOffset(3).GetAs(); + auto StringRef = Memcury::Scanner::FindStringRef(Name, true, skip); + + if (!StringRef.Get()) + return 0; + + auto FunctionPtr = StringRef.ScanFor({ 0x48, 0x8D, 0x0D }).RelativeOffset(3).GetAs(); auto PtrRef = Memcury::Scanner::FindPointerRef(FunctionPtr);