glorious update

work on rift tour, fix some crash and some bugs, added destroying gadgets when no more uses
This commit is contained in:
Milxnor
2023-05-14 09:11:55 -04:00
parent 1da6822119
commit a94005805c
18 changed files with 324 additions and 729 deletions

View File

@@ -20,13 +20,3 @@ void UFortGadgetItemDefinition::UnequipGadgetData(AFortPlayerController* PlayerC
}
}
}
void UFortGadgetItemDefinition::UpdateTrackedAttributesHook(UFortGadgetItemDefinition* GadgetItemDefinition)
{
// LOG_INFO(LogDev, "UpdateTrackedAttributesHook Return: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0)));
if (GadgetItemDefinition->ShouldDestroyGadgetWhenTrackedAttributesIsZero())
{
// PlayerState->MulticastTriggerOnGadgetTrackedAttributeDestroyedFX
}
}

View File

@@ -51,8 +51,6 @@ public:
void UnequipGadgetData(AFortPlayerController* PlayerController, UFortItem* Item);
static void UpdateTrackedAttributesHook(UFortGadgetItemDefinition* GadgetItemDefinition);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortGadgetItemDefinition");

View File

@@ -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<bool>(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);

View File

@@ -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;

View File

@@ -13,8 +13,6 @@ struct FFortGameFeatureLootTableData
TSoftObjectPtr<UDataTable> LootPackageData;
};
#ifdef EXPERIMENTAL_LOOTING
template <typename RowStructType = uint8>
void CollectDataTablesRows(const std::vector<UDataTable*>& DataTables, std::map<FName, RowStructType*>* OutMap, std::function<bool(FName, RowStructType*)> Check = []() { return true; })
{
@@ -24,7 +22,7 @@ void CollectDataTablesRows(const std::vector<UDataTable*>& 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<LootDrop> 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<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, boo
if (!bFoundPlaylistTable)
{
#ifdef brudda
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
}
else
{
LTDTables.push_back(LoadObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"));
LPTables.push_back(LoadObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client"));
#endif
}
}
// LTDTables.push_back(LoadObject<UDataTable>(L"/Game/Athena/Playlists/Playground/AthenaLootTierData_Client.AthenaLootTierData_Client"));
// LPTables.push_back(LoadObject<UDataTable>(L"/Game/Athena/Playlists/Playground/AthenaLootPackages_Client.AthenaLootPackages_Client"));
static auto FortGameFeatureDataClass = FindObject<UClass>("/Script/FortniteGame.FortGameFeatureData");
static auto FortGameFeatureDataClass = FindObject<UClass>(L"/Script/FortniteGame.FortGameFeatureData");
if (FortGameFeatureDataClass)
{
@@ -573,6 +580,8 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, boo
}
}
if (!Addresses::LoadAsset)
{
if (Fortnite_Version <= 6 || std::floor(Fortnite_Version) == 9) // ahhh
{
LTDTables.clear();
@@ -595,8 +604,11 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, boo
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);
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)
{
@@ -615,6 +627,8 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, boo
}
}
}
if (LTDTables.size() <= 0 || LPTables.size() <= 0)
{
LOG_WARN(LogLoot, "Empty tables! ({} {})", LTDTables.size(), LPTables.size());
@@ -683,640 +697,3 @@ std::vector<LootDrop> 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<FFortLootTierData*>& 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<FFortLootPackageData*>& 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<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recursive)
{
std::vector<LootDrop> LootDrops;
if (recursive > 6)
return LootDrops;
auto GameState = ((AFortGameModeAthena*)GetWorld()->GetGameMode())->GetGameStateAthena();
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
static std::vector<UDataTable*> LTDTables;
static std::vector<UDataTable*> LPTables;
static auto CompositeDataTableClass = FindObject<UClass>(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<TSoftObjectPtr<UDataTable>>(LootTierDataOffset);
static auto LootPackagesOffset = CurrentPlaylist->GetOffset("LootPackages");
auto& LootPackagesSoft = CurrentPlaylist->Get<TSoftObjectPtr<UDataTable>>(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<UDataTable>(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"));
LPTables.push_back(LoadObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client"));
}
// LTDTables.push_back(LoadObject<UDataTable>(L"/Game/Athena/Playlists/Playground/AthenaLootTierData_Client.AthenaLootTierData_Client"));
// LPTables.push_back(LoadObject<UDataTable>(L"/Game/Athena/Playlists/Playground/AthenaLootPackages_Client.AthenaLootPackages_Client"));
static auto FortGameFeatureDataClass = FindObject<UClass>("/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<FFortGameFeatureLootTableData>(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<TMap<FGameplayTag, FFortGameFeatureLootTableData>>(PlaylistOverrideLootTableDataOffset);
static auto GameplayTagContainerOffset = CurrentPlaylist->GetOffset("GameplayTagContainer");
auto GameplayTagContainer = CurrentPlaylist->GetPtr<FGameplayTagContainer>(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<TArray<UDataTable*>>(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<TMap<FGameplayTag, FFortGameFeatureLootTableData>>(PlaylistOverrideLootTableDataOffset);
static auto GameplayTagContainerOffset = CurrentPlaylist->GetOffset("GameplayTagContainer");
auto GameplayTagContainer = CurrentPlaylist->GetPtr<FGameplayTagContainer>(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<TArray<UDataTable*>>(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<TSoftObjectPtr<UDataTable>>(LootTierDataOffset);
static auto LootPackagesOffset = CurrentPlaylist->GetOffset("LootPackages");
auto& LootPackagesSoft = CurrentPlaylist->Get<TSoftObjectPtr<UDataTable>>(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<UDataTable>(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"));
LPTables.push_back(LoadObject<UDataTable>(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<FFortLootTierData*> 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<FFortLootPackageData*> 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<FFortLootPackageData*> 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<UFortWeaponItemDefinition>(ItemDef);
LootDrops.push_back(LootDrop(FFortItemEntry::MakeItemEntry(ItemDef, LootPackageCall->GetCount(), WeaponDef ? WeaponDef->GetClipSize() : 0));
}
return LootDrops;
}
#endif

View File

@@ -10,8 +10,6 @@
#include "SoftObjectPtr.h"
#include "FortItem.h"
#define EXPERIMENTAL_LOOTING
struct FFortLootPackageData
{
public:

View File

@@ -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);
}
}
}

View File

@@ -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)
{
@@ -501,3 +502,88 @@ 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<AFortPlayerStateAthena>(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<UFortItem*> ItemInstancesToRemove;
for (int i = 0; i < ItemInstances.Num(); i++)
{
auto ItemInstance = ItemInstances.at(i);
auto GadgetItemDefinition = Cast<UFortGadgetItemDefinition>(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<FFortGameplayAttributeData>(PropertyOffset)->GetCurrentValue() > 0)
{
bIsTrackedAttributesZero = false;
break; // hm
}
}
}
}
}
if (bIsTrackedAttributesZero)
{
ItemInstancesToRemove.push_back(ItemInstance);
}
}
for (auto ItemInstanceToRemove : ItemInstancesToRemove)
{
auto GadgetItemDefinition = Cast<UFortGadgetItemDefinition>(ItemInstanceToRemove->GetItemEntry()->GetItemDefinition());
WorldInventory->RemoveItem(ItemInstanceToRemove->GetItemEntry()->GetItemGuid(), nullptr, ItemInstanceToRemove->GetItemEntry()->GetCount(), true);
static auto MulticastTriggerOnGadgetTrackedAttributeDestroyedFXFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateZone.MulticastTriggerOnGadgetTrackedAttributeDestroyedFX");
PlayerState->ProcessEvent(MulticastTriggerOnGadgetTrackedAttributeDestroyedFXFn, &GadgetItemDefinition);
}
if (ItemInstancesToRemove.size() > 0)
WorldInventory->Update();
}

View File

@@ -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()
{

View File

@@ -97,7 +97,7 @@ struct FFortGameplayEffectDeliveryInfo
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.FortGameplayEffectDeliveryInfo");
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.FortGameplayEffectDeliveryInfo");
return Struct;
}
@@ -123,7 +123,7 @@ struct FFortAbilitySetDeliveryInfo
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.FortAbilitySetDeliveryInfo");
static auto Struct = FindObject<UStruct>(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<ABuildingActor>(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);
}
}

View File

@@ -562,6 +562,11 @@ std::vector<uint64> 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

View File

@@ -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<int32>(ReplicatedActivePhaseIndexOffset) = NewPhase;
static auto OnRep_ReplicatedActivePhaseIndexFn = FindObject<UFunction>("/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<int32>(ReplicatedActivePhaseIndexOffset) = Index;
static auto OnRep_ReplicatedActivePhaseIndexFn = FindObject<UFunction>("/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<UFunction>("/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<AFortGameModeAthena>(L"/Script/FortniteGame.Default__FortGameModeAthena");
static auto FortPlayerControllerZoneDefault = FindObject<AFortPlayerController>(L"/Script/FortniteGame.Default__FortPlayerControllerZone");
static auto FortPlayerControllerDefault = FindObject<AFortPlayerController>(L"/Script/FortniteGame.Default__FortPlayerController");
static auto FortPlayerControllerAthenaDefault = FindObject<AFortPlayerControllerAthena>(L"/Script/FortniteGame.Default__FortPlayerControllerAthena"); // FindObject<UClass>(L"/Game/Athena/Athena_PlayerController.Default__Athena_PlayerController_C");
static auto FortPlayerPawnAthenaDefault = FindObject<AFortPlayerPawn>(L"/Script/FortniteGame.Default__FortPlayerPawnAthena"); // FindObject<AFortPlayerPawn>(L"/Game/Athena/PlayerPawn_Athena.Default__PlayerPawn_Athena_C");
static auto FortAbilitySystemComponentAthenaDefault = FindObject<UObject>(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<UFunction>(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<UFunction>(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<UFunction>(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"));
}

View File

@@ -717,10 +717,14 @@ static inline void StartEvent()
static bool (*sub_7FF7E556D158)(UObject* MeshScriptActor) = decltype(sub_7FF7E556D158)(__int64(GetModuleHandleW(0)) + 0x3DED158);
LOG_INFO(LogDev, "sub_7FF7E556D158 {}", sub_7FF7E556D158(SpecialEventScriptMeshActor));
// if (false)
{
SpecialEventScriptMeshActor->ProcessEvent(MeshRootStartEventFn);
SpecialEventScriptMeshActor->ProcessEvent(OnRep_RootStartTimeFn);
return;
}
}
else
{
LOG_ERROR(LogEvent, "Failed to find SpecialEventScriptMeshActor");

View File

@@ -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;

View File

@@ -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";

View File

@@ -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);

View File

@@ -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);
}

7
vendor/memcury.h vendored
View File

@@ -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<uint8_t>& Bytes = std::vector<uint8_t>{ 0x48, 0x89, 0x5C }, int skip = 0) // credit ender & me
{
auto FunctionPtr = Memcury::Scanner::FindStringRef(Name, true, skip).ScanFor({ 0x48, 0x8D, 0x0D }).RelativeOffset(3).GetAs<void*>();
auto StringRef = Memcury::Scanner::FindStringRef(Name, true, skip);
if (!StringRef.Get())
return 0;
auto FunctionPtr = StringRef.ScanFor({ 0x48, 0x8D, 0x0D }).RelativeOffset(3).GetAs<void*>();
auto PtrRef = Memcury::Scanner::FindPointerRef(FunctionPtr);