mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
a bit of stuff
toys, ammo in bottom right kinda, fix lootin speeds, being inaccurate, playlist looting kindof, or some things just not working.
This commit is contained in:
@@ -96,46 +96,6 @@ void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySyste
|
||||
{
|
||||
// LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Activated {}", AbilityToActivate->GetName());
|
||||
}
|
||||
|
||||
// bro ignore this next part idk where to put it ok
|
||||
|
||||
/* static auto OwnerActorOffset = AbilitySystemComponent->GetOffset("OwnerActor");
|
||||
auto PlayerState = Cast<AFortPlayerStateAthena>(AbilitySystemComponent->Get<AActor*>(OwnerActorOffset));
|
||||
|
||||
if (!PlayerState)
|
||||
return;
|
||||
|
||||
auto Controller = Cast<AFortPlayerController>(PlayerState->GetOwner());
|
||||
LOG_INFO(LogAbilities, "Owner {}", PlayerState->GetOwner()->GetFullName());
|
||||
|
||||
if (!Controller)
|
||||
return;
|
||||
|
||||
auto Pawn = Controller->GetMyFortPawn();
|
||||
|
||||
if (!Pawn)
|
||||
return;
|
||||
|
||||
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
||||
auto WorldInventory = Controller ? Controller->GetWorldInventory() : nullptr;
|
||||
|
||||
if (!WorldInventory || !CurrentWeapon)
|
||||
return;
|
||||
|
||||
auto CurrentWeaponInstance = WorldInventory->FindItemInstance(CurrentWeapon->GetItemEntryGuid());
|
||||
auto CurrentWeaponReplicatedEntry = WorldInventory->FindReplicatedEntry(CurrentWeapon->GetItemEntryGuid());
|
||||
|
||||
static auto AmmoCountOffset = CurrentWeapon->GetOffset("AmmoCount");
|
||||
auto AmmoCount = CurrentWeapon->Get<int>(AmmoCountOffset);
|
||||
|
||||
if (CurrentWeaponReplicatedEntry->GetLoadedAmmo() != AmmoCount)
|
||||
{
|
||||
CurrentWeaponInstance->GetItemEntry()->GetLoadedAmmo() = AmmoCount;
|
||||
CurrentWeaponReplicatedEntry->GetLoadedAmmo() = AmmoCount;
|
||||
|
||||
WorldInventory->GetItemList().MarkItemDirty(CurrentWeaponInstance->GetItemEntry());
|
||||
WorldInventory->GetItemList().MarkItemDirty(CurrentWeaponReplicatedEntry);
|
||||
} */
|
||||
}
|
||||
|
||||
FGameplayAbilitySpecHandle UAbilitySystemComponent::GiveAbilityEasy(UClass* AbilityClass)
|
||||
|
||||
@@ -72,6 +72,8 @@ static UObject* GetPlaylistToUse()
|
||||
// Playlist = FindObject("/MoleGame/Playlists/Playlist_MoleGame.Playlist_MoleGame");
|
||||
// Playlist = FindObject("/Game/Athena/Playlists/DADBRO/Playlist_DADBRO_Squads_8.Playlist_DADBRO_Squads_8");
|
||||
|
||||
// Playlist = FindObject("/Game/Athena/Playlists/Low/Playlist_Low_Solo.Playlist_Low_Solo");
|
||||
|
||||
if (Globals::bCreative)
|
||||
Playlist = FindObject("/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2");
|
||||
|
||||
@@ -613,7 +615,9 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
|
||||
|
||||
auto GameState = Cast<AFortGameStateAthena>(GameMode->GetGameState());
|
||||
|
||||
auto Playlist = GameState->GetCurrentPlaylist();
|
||||
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
|
||||
|
||||
auto Playlist = CurrentPlaylistDataOffset == -1 && Fortnite_Version < 6 ? nullptr : GameState->GetCurrentPlaylist();
|
||||
|
||||
static int CurrentTeamMembers = 0; // bad
|
||||
static int Current = 3;
|
||||
|
||||
@@ -170,7 +170,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
||||
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
||||
}
|
||||
|
||||
bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count)
|
||||
bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count, bool bForceRemoval)
|
||||
{
|
||||
if (bShouldUpdate)
|
||||
*bShouldUpdate = false;
|
||||
@@ -188,8 +188,11 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
|
||||
|
||||
auto NewCount = ReplicatedEntry->GetCount() - Count;
|
||||
|
||||
if (NewCount > 0)
|
||||
if (NewCount > 0 || (ItemDefinition->ShouldPersistWhenFinalStackEmpty() && !bForceRemoval))
|
||||
{
|
||||
if (ItemDefinition->ShouldPersistWhenFinalStackEmpty())
|
||||
NewCount = NewCount < 0 ? 0 : NewCount; // min(NewCount, 0) or something i forgot
|
||||
|
||||
ItemInstance->GetItemEntry()->GetCount() = NewCount;
|
||||
ReplicatedEntry->GetCount() = NewCount;
|
||||
|
||||
@@ -291,6 +294,28 @@ UFortItem* AFortInventory::FindItemInstance(UFortItemDefinition* ItemDefinition)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AFortInventory::CorrectLoadedAmmo(const FGuid& Guid, int NewAmmoCount)
|
||||
{
|
||||
auto CurrentWeaponInstance = FindItemInstance(Guid);
|
||||
|
||||
if (!CurrentWeaponInstance)
|
||||
return;
|
||||
|
||||
auto CurrentWeaponReplicatedEntry = FindReplicatedEntry(Guid);
|
||||
|
||||
if (!CurrentWeaponReplicatedEntry)
|
||||
return;
|
||||
|
||||
if (CurrentWeaponReplicatedEntry->GetLoadedAmmo() != NewAmmoCount)
|
||||
{
|
||||
CurrentWeaponInstance->GetItemEntry()->GetLoadedAmmo() = NewAmmoCount;
|
||||
CurrentWeaponReplicatedEntry->GetLoadedAmmo() = NewAmmoCount;
|
||||
|
||||
GetItemList().MarkItemDirty(CurrentWeaponInstance->GetItemEntry());
|
||||
GetItemList().MarkItemDirty(CurrentWeaponReplicatedEntry);
|
||||
}
|
||||
}
|
||||
|
||||
UFortItem* AFortInventory::FindItemInstance(const FGuid& Guid)
|
||||
{
|
||||
auto& ItemInstances = GetItemList().GetItemInstances();
|
||||
|
||||
@@ -117,12 +117,14 @@ public:
|
||||
}
|
||||
|
||||
std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AddItem(UFortItemDefinition* ItemDefinition, bool* bShouldUpdate, int Count = 1, int LoadedAmmo = -1, bool bShouldAddToStateValues = false);
|
||||
bool RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count);
|
||||
bool RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count, bool bForceRemoval = false);
|
||||
void ModifyCount(UFortItem* ItemInstance, int New, bool bRemove = false, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries = nullptr, bool bUpdate = true);
|
||||
|
||||
UFortItem* GetPickaxeInstance();
|
||||
UFortItem* FindItemInstance(UFortItemDefinition* ItemDefinition);
|
||||
|
||||
void CorrectLoadedAmmo(const FGuid& Guid, int NewAmmoCount);
|
||||
|
||||
UFortItem* FindItemInstance(const FGuid& Guid);
|
||||
FFortItemEntry* FindReplicatedEntry(const FGuid& Guid);
|
||||
};
|
||||
@@ -11,8 +11,9 @@ char UFortInventoryInterface::RemoveInventoryItemHook(__int64 a1, FGuid a2, int
|
||||
int SuperAdditionalOffset = Engine_Version >= 427 ? 16 : 8;
|
||||
auto ControllerObject = (UObject*)(__int64(a1) - (FortPlayerControllerSuperSize + SuperAdditionalOffset));
|
||||
|
||||
LOG_INFO(LogDev, "FortPlayerControllerSuperSize: {}", FortPlayerControllerSuperSize);
|
||||
LOG_INFO(LogDev, "ControllerObject: {}", ControllerObject->GetFullName());
|
||||
LOG_INFO(LogDev, "bForceRemoval: {}", (bool)bForceRemoval);
|
||||
// LOG_INFO(LogDev, "FortPlayerControllerSuperSize: {}", FortPlayerControllerSuperSize);
|
||||
// LOG_INFO(LogDev, "ControllerObject: {}", ControllerObject->GetFullName());
|
||||
|
||||
if (!ControllerObject)
|
||||
return false;
|
||||
@@ -28,7 +29,7 @@ char UFortInventoryInterface::RemoveInventoryItemHook(__int64 a1, FGuid a2, int
|
||||
return false;
|
||||
|
||||
bool bShouldUpdate = false;
|
||||
WorldInventory->RemoveItem(a2, &bShouldUpdate, Count);
|
||||
WorldInventory->RemoveItem(a2, &bShouldUpdate, Count, bForceRemoval);
|
||||
|
||||
if (bShouldUpdate)
|
||||
WorldInventory->Update();
|
||||
|
||||
@@ -312,7 +312,7 @@ void UFortKismetLibrary::K2_RemoveItemFromPlayerByGuidHook(UObject* Context, FFr
|
||||
return K2_RemoveItemFromPlayerByGuidOriginal(Context, Stack, Ret);
|
||||
|
||||
bool bShouldUpdate = false;
|
||||
WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, AmountToRemove);
|
||||
WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, AmountToRemove, bForceRemoval);
|
||||
|
||||
if (bShouldUpdate)
|
||||
WorldInventory->Update();
|
||||
@@ -374,8 +374,9 @@ void UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook(UObject* Context, FFram
|
||||
if (!WorldInventory)
|
||||
return K2_RemoveFortItemFromPlayerOriginal(Context, Stack, Ret);
|
||||
|
||||
LOG_INFO(LogDev, "bForceRemoval: {}", bForceRemoval);
|
||||
bool bShouldUpdate = false;
|
||||
WorldInventory->RemoveItem(Item->GetItemEntry()->GetItemGuid(), &bShouldUpdate, AmountToRemove);
|
||||
WorldInventory->RemoveItem(Item->GetItemEntry()->GetItemGuid(), &bShouldUpdate, AmountToRemove, bForceRemoval);
|
||||
|
||||
if (bShouldUpdate)
|
||||
WorldInventory->Update();
|
||||
|
||||
@@ -7,38 +7,42 @@
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "FortGameModeAthena.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
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* GetLootTierData2(std::vector<FFortLootTierData*>& LootTierData, bool bPrint)
|
||||
{
|
||||
float TotalWeight = 0;
|
||||
FFortLootTierData* SelectedItem = nullptr;
|
||||
|
||||
for (auto Item : LootTierData)
|
||||
{
|
||||
TotalWeight += Item->GetWeight();
|
||||
}
|
||||
|
||||
float RandomNumber = TotalWeight * (rand() * 0.000030518509); // UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
|
||||
|
||||
FFortLootTierData* SelectedItem = nullptr;
|
||||
|
||||
if (bPrint)
|
||||
{
|
||||
std::cout << std::format("TotalWeight: {}\n", TotalWeight);
|
||||
}
|
||||
float RandomNumber = GetRandomFloatForLooting(0, 1);
|
||||
float cumulative_weight = 0.0f;
|
||||
|
||||
for (auto Item : LootTierData)
|
||||
{
|
||||
if (bPrint)
|
||||
{
|
||||
std::cout << std::format("Rand: {} Weight: {}\n", RandomNumber, Item->GetWeight());
|
||||
}
|
||||
cumulative_weight += Item->GetWeight() / TotalWeight;
|
||||
|
||||
if (RandomNumber <= Item->GetWeight())
|
||||
{
|
||||
SelectedItem = Item;
|
||||
break;
|
||||
}
|
||||
|
||||
RandomNumber -= Item->GetWeight();
|
||||
}
|
||||
|
||||
if (!SelectedItem)
|
||||
@@ -50,25 +54,25 @@ static FFortLootTierData* GetLootTierData2(std::vector<FFortLootTierData*>& Loot
|
||||
static FFortLootPackageData* GetLootPackage2(std::vector<FFortLootPackageData*>& LootPackages)
|
||||
{
|
||||
float TotalWeight = 0;
|
||||
FFortLootPackageData* SelectedItem = nullptr;
|
||||
|
||||
for (auto Item : LootPackages)
|
||||
{
|
||||
TotalWeight += Item->GetWeight();
|
||||
}
|
||||
|
||||
float RandomNumber = TotalWeight * (rand() * 0.000030518509); // UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
|
||||
|
||||
FFortLootPackageData* SelectedItem = nullptr;
|
||||
float RandomNumber = GetRandomFloatForLooting(0, 1);
|
||||
float cumulative_weight = 0.0f;
|
||||
|
||||
for (auto Item : LootPackages)
|
||||
{
|
||||
cumulative_weight += Item->GetWeight() / TotalWeight;
|
||||
|
||||
if (RandomNumber <= Item->GetWeight())
|
||||
{
|
||||
SelectedItem = Item;
|
||||
break;
|
||||
}
|
||||
|
||||
RandomNumber -= Item->GetWeight();
|
||||
}
|
||||
|
||||
if (!SelectedItem)
|
||||
@@ -79,31 +83,20 @@ static FFortLootPackageData* GetLootPackage2(std::vector<FFortLootPackageData*>&
|
||||
|
||||
static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootTierData, bool bPrint)
|
||||
{
|
||||
return GetLootTierData2(LootTierData, bPrint);
|
||||
// return GetLootTierData2(LootTierData, bPrint);
|
||||
|
||||
float TotalWeight = 0;
|
||||
FFortLootTierData* SelectedItem = nullptr;
|
||||
|
||||
for (auto Item : LootTierData)
|
||||
{
|
||||
TotalWeight += Item->GetWeight();
|
||||
}
|
||||
|
||||
float RandomNumber = UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
|
||||
|
||||
FFortLootTierData* SelectedItem = nullptr;
|
||||
|
||||
if (bPrint)
|
||||
{
|
||||
std::cout << std::format("TotalWeight: {}\n", TotalWeight);
|
||||
}
|
||||
float RandomNumber = GetRandomFloatForLooting(0, TotalWeight); // is -1 needed?
|
||||
|
||||
for (auto Item : LootTierData)
|
||||
{
|
||||
if (bPrint)
|
||||
{
|
||||
std::cout << std::format("Rand: {} Weight: {}\n", RandomNumber, Item->GetWeight());
|
||||
}
|
||||
|
||||
if (RandomNumber <= Item->GetWeight())
|
||||
{
|
||||
SelectedItem = Item;
|
||||
@@ -121,18 +114,17 @@ static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootT
|
||||
|
||||
static FFortLootPackageData* GetLootPackage(std::vector<FFortLootPackageData*>& LootPackages)
|
||||
{
|
||||
return GetLootPackage2(LootPackages);
|
||||
// return GetLootPackage2(LootPackages);
|
||||
|
||||
float TotalWeight = 0;
|
||||
FFortLootPackageData* SelectedItem = nullptr;
|
||||
|
||||
for (auto Item : LootPackages)
|
||||
{
|
||||
TotalWeight += Item->GetWeight();
|
||||
}
|
||||
|
||||
float RandomNumber = UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
|
||||
|
||||
FFortLootPackageData* SelectedItem = nullptr;
|
||||
float RandomNumber = GetRandomFloatForLooting(0, TotalWeight); // is -1 needed?
|
||||
|
||||
for (auto Item : LootPackages)
|
||||
{
|
||||
@@ -158,8 +150,6 @@ public:
|
||||
TSoftObjectPtr<UDataTable> LootPackageData; // 0x28(0x28)(Edit, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
};
|
||||
|
||||
|
||||
|
||||
std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recursive)
|
||||
{
|
||||
std::vector<LootDrop> LootDrops;
|
||||
@@ -168,8 +158,9 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
return LootDrops;
|
||||
|
||||
auto GameState = ((AFortGameModeAthena*)GetWorld()->GetGameMode())->GetGameStateAthena();
|
||||
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
|
||||
|
||||
// #define BELUGA
|
||||
#define BELUGA
|
||||
|
||||
#ifndef BELUGA
|
||||
/* static */ std::vector<UDataTable*> LTDTables;
|
||||
@@ -183,19 +174,56 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
static bool bHasFoundTables = false;
|
||||
#endif
|
||||
|
||||
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
||||
auto CurrentPlaylist = CurrentPlaylistDataOffset == -1 && Fortnite_Version < 6 ? nullptr : GameState->GetCurrentPlaylist();
|
||||
|
||||
if (!bHasFoundTables)
|
||||
{
|
||||
bHasFoundTables = true;
|
||||
|
||||
bool bFoundPlaylistTable = false;
|
||||
|
||||
static auto DataTableClass = FindObject<UClass>("/Script/Engine.DataTable");
|
||||
static auto CompositeDataTableClass = FindObject<UClass>("/Script/Engine.CompositeDataTable");
|
||||
|
||||
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 : DataTableClass, true);
|
||||
auto StrongLootPackage = LootPackagesSoft.Get(LootPackageTableIsComposite ? CompositeDataTableClass : DataTableClass, 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"));
|
||||
|
||||
#ifdef BELUGA
|
||||
static auto FortGameFeatureDataClass = FindObject<UClass>("/Script/FortniteGame.FortGameFeatureData");
|
||||
static auto DataTableClass = FindObject<UClass>("/Script/Engine.DataTable");
|
||||
static auto CompositeDataTableClass = FindObject<UClass>("/Script/Engine.CompositeDataTable");
|
||||
|
||||
if (FortGameFeatureDataClass)
|
||||
{
|
||||
@@ -340,15 +368,17 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for (int i = 0; i < LTDTables.size(); i++)
|
||||
for (int i = 0; i < LTDTables.size(); i++)
|
||||
{
|
||||
LTDTables.at(i)->AddToRoot();
|
||||
LOG_INFO(LogDev, "[{}] LTD {}", i, LTDTables.at(i)->GetFullName());
|
||||
}
|
||||
|
||||
for (int i = 0; i < LPTables.size(); i++)
|
||||
{
|
||||
LPTables.at(i)->AddToRoot();
|
||||
LOG_INFO(LogDev, "[{}] LP {}", i, LPTables.at(i)->GetFullName());
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<FFortLootTierData*> TierGroupLTDs;
|
||||
@@ -357,7 +387,10 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
{
|
||||
auto LTD = LTDTables[p];
|
||||
|
||||
if (!LTD)
|
||||
// if (bPrint)
|
||||
// LOG_INFO(LogLoot, "LTD: {}", !LTD->IsValidLowLevel() ? "BadRead" : LTD->GetFullName());
|
||||
|
||||
if (!LTD->IsValidLowLevel())
|
||||
continue;
|
||||
|
||||
auto& LTDRowMap = LTD->GetRowMap();
|
||||
@@ -365,9 +398,6 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
|
||||
// auto TierGroupNameStr = TierGroupName.ToString();
|
||||
|
||||
// if (bPrint)
|
||||
// LOG_INFO(LogLoot, "LTDRowMapNum: {} LTD: {}", LTDRowMapNum, IsBadReadPtr(LTD, 8) ? "BadRead" : LTD->GetFullName());
|
||||
|
||||
for (int i = 0; i < LTDRowMapNum; i++)
|
||||
{
|
||||
auto& CurrentLTD = LTDRowMap.Pairs.Elements[i].ElementData.Value;
|
||||
@@ -474,6 +504,10 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
for (int p = 0; p < LPTables.size(); p++)
|
||||
{
|
||||
auto LP = LPTables[p];
|
||||
|
||||
if (!LP->IsValidLowLevel())
|
||||
continue;
|
||||
|
||||
auto& LPRowMap = LP->GetRowMap();
|
||||
|
||||
for (int i = 0; i < LPRowMap.Pairs.Elements.Num(); i++)
|
||||
@@ -573,6 +607,9 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
{
|
||||
for (int p = 0; p < LPTables.size(); p++)
|
||||
{
|
||||
if (!LPTables[p]->IsValidLowLevel())
|
||||
continue;
|
||||
|
||||
auto& LPRowMap = LPTables[p]->GetRowMap();
|
||||
|
||||
for (int j = 0; j < LPRowMap.Pairs.Elements.Num(); j++)
|
||||
|
||||
@@ -145,7 +145,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
|
||||
auto SwappedPickup = SpawnPickup(ItemDefinitionToSwap, PawnLoc, ItemEntryToSwap->GetCount(),
|
||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, ItemEntryToSwap->GetLoadedAmmo(), Pawn);
|
||||
|
||||
WorldInventory->RemoveItem(CurrentItemGuid, nullptr, ItemEntryToSwap->GetCount());
|
||||
WorldInventory->RemoveItem(CurrentItemGuid, nullptr, ItemEntryToSwap->GetCount(), true);
|
||||
|
||||
bHasSwapped = true;
|
||||
|
||||
|
||||
@@ -489,6 +489,34 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
|
||||
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
|
||||
}
|
||||
|
||||
AActor* AFortPlayerController::SpawnToyInstanceHook(UObject* Context, FFrame* Stack, AActor** Ret)
|
||||
{
|
||||
LOG_INFO(LogDev, "SpawnToyInstance!");
|
||||
|
||||
auto PlayerController = Cast<AFortPlayerController>(Context);
|
||||
|
||||
UClass* ToyClass = nullptr;
|
||||
FTransform SpawnPosition;
|
||||
|
||||
Stack->StepCompiledIn(&ToyClass);
|
||||
Stack->StepCompiledIn(&SpawnPosition);
|
||||
|
||||
SpawnToyInstanceOriginal(Context, Stack, Ret);
|
||||
|
||||
if (!ToyClass)
|
||||
return nullptr;
|
||||
|
||||
FActorSpawnParameters SpawnParameters{};
|
||||
SpawnParameters.Owner = PlayerController;
|
||||
auto NewToy = GetWorld()->SpawnActor<AActor>(ToyClass, SpawnPosition, SpawnParameters);
|
||||
|
||||
static auto ActiveToyInstancesOffset = PlayerController->GetOffset("ActiveToyInstances");
|
||||
|
||||
|
||||
*Ret = NewToy;
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
void AFortPlayerController::DropSpecificItemHook(UObject* Context, FFrame& Stack, void* Ret)
|
||||
{
|
||||
UFortItemDefinition* DropItemDef = nullptr;
|
||||
@@ -546,7 +574,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
|
||||
|
||||
bool bShouldUpdate = false;
|
||||
|
||||
if (!WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, Count))
|
||||
if (!WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, Count, true))
|
||||
return;
|
||||
|
||||
if (bShouldUpdate)
|
||||
@@ -564,6 +592,7 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
|
||||
UObject* AbilityToUse = nullptr;
|
||||
|
||||
static auto AthenaSprayItemDefinitionClass = FindObject<UClass>("/Script/FortniteGame.AthenaSprayItemDefinition");
|
||||
static auto AthenaToyItemDefinitionClass = FindObject<UClass>("/Script/FortniteGame.AthenaToyItemDefinition");
|
||||
|
||||
if (EmoteAsset->IsA(AthenaSprayItemDefinitionClass))
|
||||
{
|
||||
@@ -571,6 +600,21 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
|
||||
AbilityToUse = SprayGameplayAbilityDefault;
|
||||
}
|
||||
|
||||
else if (EmoteAsset->IsA(AthenaToyItemDefinitionClass))
|
||||
{
|
||||
static auto ToySpawnAbilityOffset = EmoteAsset->GetOffset("ToySpawnAbility");
|
||||
auto& ToySpawnAbilitySoft = EmoteAsset->Get<TSoftObjectPtr<UClass>>(ToySpawnAbilityOffset);
|
||||
|
||||
static auto BGAClass = FindObject<UClass>("/Script/Engine.BlueprintGeneratedClass");
|
||||
|
||||
auto ToySpawnAbility = ToySpawnAbilitySoft.Get(BGAClass, true);
|
||||
|
||||
if (ToySpawnAbility)
|
||||
AbilityToUse = ToySpawnAbility->CreateDefaultObject();
|
||||
}
|
||||
|
||||
// LOG_INFO(LogDev, "Before AbilityToUse: {}", AbilityToUse ? AbilityToUse->GetFullName() : "InvalidObject");
|
||||
|
||||
if (!AbilityToUse)
|
||||
{
|
||||
static auto EmoteGameplayAbilityDefault = FindObject("/Game/Abilities/Emotes/GAB_Emote_Generic.Default__GAB_Emote_Generic_C");
|
||||
@@ -767,7 +811,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
||||
|
||||
for (auto& Pair : GuidAndCountsToRemove)
|
||||
{
|
||||
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second);
|
||||
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true);
|
||||
}
|
||||
|
||||
WorldInventory->Update();
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
static inline void (*ServerAttemptInteractOriginal)(UObject* Context, FFrame* Stack, void* Ret);
|
||||
static inline void (*ServerEditBuildingActorOriginal)(UObject* Context, FFrame& Stack, void* Ret);
|
||||
static inline void (*DropSpecificItemOriginal)(UObject* Context, FFrame& Stack, void* Ret);
|
||||
static inline AActor* (*SpawnToyInstanceOriginal)(UObject* Context, FFrame* Stack, AActor** Ret);
|
||||
|
||||
void ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot);
|
||||
|
||||
@@ -69,6 +70,7 @@ public:
|
||||
static void ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation);
|
||||
// static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
|
||||
static void ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
static AActor* SpawnToyInstanceHook(UObject* Context, FFrame* Stack, AActor** Ret);
|
||||
static void DropSpecificItemHook(UObject* Context, FFrame& Stack, void* Ret);
|
||||
|
||||
static void ServerDropAllItemsHook(AFortPlayerController* PlayerController, UFortItemDefinition* IgnoreItemDef);
|
||||
|
||||
@@ -43,7 +43,7 @@ void AFortPlayerStateAthena::ServerSetInAircraftHook(UObject* Context, FFrame& S
|
||||
|
||||
for (auto& Pair : GuidAndCountsToRemove)
|
||||
{
|
||||
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second);
|
||||
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true);
|
||||
}
|
||||
|
||||
WorldInventory->Update();
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
#include "FortWeapon.h"
|
||||
#include "FortPlayerPawn.h"
|
||||
|
||||
#include "reboot.h"
|
||||
#include "FortPlayerController.h"
|
||||
|
||||
void AFortWeapon::ServerReleaseWeaponAbilityHook(UObject* Context, FFrame* Stack, void* Ret)
|
||||
{
|
||||
// I don't know where to put this..
|
||||
|
||||
auto Weapon = (AFortWeapon*)Context;
|
||||
auto Pawn = Cast<AFortPlayerPawn>(Weapon->GetOwner());
|
||||
|
||||
// LOG_INFO(LogDev, "Owner: {}", Weapon->GetOwner() ? Weapon->GetOwner()->GetFullName() : "InvalidObject");
|
||||
|
||||
if (!Pawn)
|
||||
return ServerReleaseWeaponAbilityOriginal(Context, Stack, Ret);
|
||||
|
||||
auto Controller = Cast<AFortPlayerController>(Pawn->GetController());
|
||||
auto CurrentWeapon = Weapon; // Pawn->GetCurrentWeapon();
|
||||
auto WorldInventory = Controller ? Controller->GetWorldInventory() : nullptr;
|
||||
|
||||
if (!WorldInventory || !CurrentWeapon)
|
||||
return ServerReleaseWeaponAbilityOriginal(Context, Stack, Ret);
|
||||
|
||||
static auto AmmoCountOffset = CurrentWeapon->GetOffset("AmmoCount");
|
||||
auto AmmoCount = CurrentWeapon->Get<int>(AmmoCountOffset);
|
||||
|
||||
WorldInventory->CorrectLoadedAmmo(CurrentWeapon->GetItemEntryGuid(), AmmoCount);
|
||||
|
||||
return ServerReleaseWeaponAbilityOriginal(Context, Stack, Ret);
|
||||
}
|
||||
|
||||
UClass* AFortWeapon::StaticClass()
|
||||
{
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Actor.h"
|
||||
#include "GameplayAbilitySpec.h"
|
||||
#include "Stack.h"
|
||||
|
||||
class AFortWeapon : public AActor
|
||||
{
|
||||
public:
|
||||
static inline void (*ServerReleaseWeaponAbilityOriginal)(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
template <typename T = class UFortWeaponItemDefinition>
|
||||
T* GetWeaponData()
|
||||
{
|
||||
@@ -18,5 +22,7 @@ public:
|
||||
return Get<FGuid>(ItemEntryGuidOffset);
|
||||
}
|
||||
|
||||
static void ServerReleaseWeaponAbilityHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
static UClass* StaticClass();
|
||||
};
|
||||
@@ -19,6 +19,13 @@ public:
|
||||
return ReadBitfieldValue(bDropOnDeathOffset, bDropOnDeathFieldMask);
|
||||
}
|
||||
|
||||
bool ShouldPersistWhenFinalStackEmpty()
|
||||
{
|
||||
static auto bPersistInInventoryWhenFinalStackEmptyOffset = GetOffset("bPersistInInventoryWhenFinalStackEmpty");
|
||||
static auto bPersistInInventoryWhenFinalStackEmptyFieldMask = GetFieldMask(GetProperty("bPersistInInventoryWhenFinalStackEmpty"));
|
||||
return ReadBitfieldValue(bPersistInInventoryWhenFinalStackEmptyOffset, bPersistInInventoryWhenFinalStackEmptyFieldMask);
|
||||
}
|
||||
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortWorldItemDefinition");
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "Class.h"
|
||||
#include "KismetSystemLibrary.h"
|
||||
#include "UObjectArray.h"
|
||||
|
||||
FName* getFNameOfProp(void* Property)
|
||||
{
|
||||
@@ -100,3 +101,35 @@ bool UObject::IsA(UClass* otherClass)
|
||||
static auto Class = FindObject<UClass>("/Script/CoreUObject.Object");
|
||||
return Class;
|
||||
} */
|
||||
|
||||
void UObject::AddToRoot()
|
||||
{
|
||||
auto Item = GetItemByIndex(InternalIndex);
|
||||
|
||||
if (!Item)
|
||||
{
|
||||
LOG_INFO(LogDev, "Invalid item");
|
||||
return;
|
||||
}
|
||||
|
||||
Item->SetRootSet();
|
||||
}
|
||||
|
||||
bool UObject::IsValidLowLevel()
|
||||
{
|
||||
if (this == nullptr)
|
||||
{
|
||||
// UE_LOG(LogUObjectBase, Warning, TEXT("NULL object"));
|
||||
return false;
|
||||
}
|
||||
if (IsBadReadPtr(this, 8)) // needed?
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!ClassPrivate)
|
||||
{
|
||||
// UE_LOG(LogUObjectBase, Warning, TEXT("Object is not registered"));
|
||||
return false;
|
||||
}
|
||||
return ChunkedObjects ? ChunkedObjects->IsValid(this) : UnchunkedObjects ? UnchunkedObjects->IsValid(this) : false;
|
||||
}
|
||||
@@ -88,5 +88,8 @@ public:
|
||||
template <typename T = UObject*>
|
||||
T* GetPtr(const std::string& ChildName) { return GetPtr<T>(GetOffset(ChildName)); }
|
||||
|
||||
void AddToRoot();
|
||||
bool IsValidLowLevel();
|
||||
|
||||
// static class UClass* StaticClass();
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "inc.h"
|
||||
|
||||
enum EObjectFlags
|
||||
{
|
||||
RF_NoFlags = 0x00000000,
|
||||
@@ -33,3 +35,31 @@ enum EObjectFlags
|
||||
RF_HasExternalPackage = 0x10000000,
|
||||
RF_AllocatedInSharedPage = 0x80000000,
|
||||
};
|
||||
|
||||
enum class EInternalObjectFlags : int
|
||||
{
|
||||
None = 0,
|
||||
|
||||
LoaderImport = 1 << 20, ///< Object is ready to be imported by another package during loading
|
||||
Garbage = 1 << 21, ///< Garbage from logical point of view and should not be referenced. This flag is mirrored in EObjectFlags as RF_Garbage for performance
|
||||
PersistentGarbage = 1 << 22, ///< Same as above but referenced through a persistent reference so it can't be GC'd
|
||||
ReachableInCluster = 1 << 23, ///< External reference to object in cluster exists
|
||||
ClusterRoot = 1 << 24, ///< Root of a cluster
|
||||
Native = 1 << 25, ///< Native (UClass only).
|
||||
Async = 1 << 26, ///< Object exists only on a different thread than the game thread.
|
||||
AsyncLoading = 1 << 27, ///< Object is being asynchronously loaded.
|
||||
Unreachable = 1 << 28, ///< Object is not reachable on the object graph.
|
||||
// PendingKill UE_DEPRECATED(5.0, "PendingKill flag should no longer be used. Use Garbage flag instead.") = 1 << 29, ///< Objects that are pending destruction (invalid for gameplay but valid objects). This flag is mirrored in EObjectFlags as RF_PendingKill for performance
|
||||
RootSet = 1 << 30, ///< Object will not be garbage collected, even if unreferenced.
|
||||
PendingConstruction = 1 << 31 ///< Object didn't have its class constructor called yet (only the UObjectBase one to initialize its most basic members)
|
||||
|
||||
/* GarbageCollectionKeepFlags = Native | Async | AsyncLoading | LoaderImport,
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
MirroredFlags = Garbage | PendingKill, /// Flags mirrored in EObjectFlags
|
||||
|
||||
//~ Make sure this is up to date!
|
||||
AllFlags = LoaderImport | Garbage | PersistentGarbage | ReachableInCluster | ClusterRoot | Native | Async | AsyncLoading | Unreachable | PendingKill | RootSet | PendingConstruction
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS */
|
||||
};
|
||||
|
||||
ENUM_CLASS_FLAGS(EInternalObjectFlags)
|
||||
@@ -19,6 +19,19 @@ struct TSoftObjectPtr
|
||||
public:
|
||||
FSoftObjectPtr SoftObjectPtr;
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
if (Engine_Version <= 416)
|
||||
{
|
||||
auto& AssetPtr = *(TAssetPtr<T>*)this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SoftObjectPtr.ObjectID.AssetPathName.ComparisonIndex.Value;
|
||||
}
|
||||
}
|
||||
|
||||
T* Get(UClass* ClassToLoad = nullptr, bool bTryToLoad = false)
|
||||
{
|
||||
if (Engine_Version <= 416)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "inc.h"
|
||||
|
||||
#include "Object.h"
|
||||
#include "ObjectMacros.h"
|
||||
|
||||
struct FUObjectItem
|
||||
{
|
||||
@@ -10,6 +11,24 @@ struct FUObjectItem
|
||||
int32 Flags;
|
||||
int32 ClusterRootIndex;
|
||||
int32 SerialNumber;
|
||||
|
||||
FORCEINLINE void SetFlag(EInternalObjectFlags FlagToSet)
|
||||
{
|
||||
// static_assert(sizeof(int32) == sizeof(Flags), "Flags must be 32-bit for atomics.");
|
||||
int32 StartValue = int32(Flags);
|
||||
|
||||
if ((StartValue & int32(FlagToSet)) == int32(FlagToSet))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int32 NewValue = StartValue | int32(FlagToSet);
|
||||
}
|
||||
|
||||
FORCEINLINE void SetRootSet()
|
||||
{
|
||||
SetFlag(EInternalObjectFlags::RootSet);
|
||||
}
|
||||
};
|
||||
|
||||
class FFixedUObjectArray
|
||||
@@ -28,6 +47,34 @@ public:
|
||||
return &Objects[Index];
|
||||
}
|
||||
|
||||
bool IsValid(UObject* Object)
|
||||
{
|
||||
int32 Index = Object->InternalIndex;
|
||||
if (Index == -1)
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Object is not in global object array"));
|
||||
return false;
|
||||
}
|
||||
if (!IsValidIndex(Index))
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Invalid object index %i"), Index);
|
||||
return false;
|
||||
}
|
||||
|
||||
FUObjectItem* Slot = GetItemByIndex(Index);
|
||||
if (!Slot || Slot->Object == nullptr)
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Empty slot"));
|
||||
return false;
|
||||
}
|
||||
if (Slot->Object != Object)
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Other object in slot"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FORCEINLINE UObject* GetObjectByIndex(int32 Index)
|
||||
{
|
||||
if (auto Item = GetItemByIndex(Index))
|
||||
@@ -69,6 +116,34 @@ public:
|
||||
return Chunk + WithinChunkIndex;
|
||||
}
|
||||
|
||||
bool IsValid(UObject* Object)
|
||||
{
|
||||
int32 Index = Object->InternalIndex;
|
||||
if (Index == -1)
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Object is not in global object array"));
|
||||
return false;
|
||||
}
|
||||
if (!IsValidIndex(Index))
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Invalid object index %i"), Index);
|
||||
return false;
|
||||
}
|
||||
|
||||
FUObjectItem* Slot = GetItemByIndex(Index);
|
||||
if (!Slot || Slot->Object == nullptr)
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Empty slot"));
|
||||
return false;
|
||||
}
|
||||
if (Slot->Object != Object)
|
||||
{
|
||||
// UE_LOG(LogUObjectArray, Warning, TEXT("Other object in slot"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FORCEINLINE UObject* GetObjectByIndex(int32 Index)
|
||||
{
|
||||
if (auto Item = GetItemByIndex(Index))
|
||||
@@ -85,3 +160,8 @@ FORCEINLINE UObject* GetObjectByIndex(int32 Index)
|
||||
{
|
||||
return ChunkedObjects ? ChunkedObjects->GetObjectByIndex(Index) : UnchunkedObjects->GetObjectByIndex(Index);
|
||||
}
|
||||
|
||||
FORCEINLINE FUObjectItem* GetItemByIndex(int32 Index)
|
||||
{
|
||||
return ChunkedObjects ? ChunkedObjects->GetItemByIndex(Index) : UnchunkedObjects->GetItemByIndex(Index);
|
||||
}
|
||||
@@ -393,12 +393,6 @@ std::vector<uint64> Addresses::GetFunctionsToNull()
|
||||
toNull.push_back(Memcury::Scanner::FindPattern("40 57 41 56 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 0F B6 FA 44 8B F1 74 3A 80 3D ? ? ? ? ? 0F 82").Get()); // collect garbage
|
||||
}
|
||||
|
||||
if (Engine_Version == 500)
|
||||
{
|
||||
// toNull.push_back(Memcury::Scanner::FindPattern("").Get()); // collectgarbage
|
||||
// toNull.push_back(Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 40 48 8B FA 48 8B D9 48 85 D2 0F 84 ? ? ? ? 8B").Get()); // idk lmfao
|
||||
}
|
||||
|
||||
if (Fortnite_Version == 12.61)
|
||||
{
|
||||
// toNull.push_back(Memcury::Scanner::FindPattern("48 89 4C 24 ? 55 56 57 41 56 48 81 EC ? ? ? ? 4C 8B B1 ? ? ? ? 33 F6 4C 89 B4 24 ? ? ? ? 48 8B").Get()); // fritter crash
|
||||
@@ -409,9 +403,9 @@ 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 (Fortnite_Version == 17.30)
|
||||
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());
|
||||
// toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 70 08 48 89 78 10 55 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 ED").Get()); // collectgarbage
|
||||
}
|
||||
|
||||
if (Fortnite_Version == 17.50)
|
||||
@@ -419,6 +413,12 @@ std::vector<uint64> Addresses::GetFunctionsToNull()
|
||||
toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A").Get()); // no reservation in game
|
||||
}
|
||||
|
||||
if (Engine_Version == 500)
|
||||
{
|
||||
// toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 F6 0F 29 70 A8 44 38 35").Get()); // zone
|
||||
// toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 55 56 57 41 54 41 55 41 56 41 57 48 8D 68 A8 48 81 EC ? ? ? ? 45 33 FF").Get()); // Garbage collection
|
||||
}
|
||||
|
||||
toNull.push_back(Addresses::ChangeGameSessionId);
|
||||
|
||||
return toNull;
|
||||
|
||||
@@ -76,13 +76,3 @@ namespace Offsets
|
||||
void FindAll();
|
||||
void Print();
|
||||
}
|
||||
|
||||
#define ENUM_CLASS_FLAGS(Enum) \
|
||||
inline Enum& operator|=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs | (__underlying_type(Enum))Rhs); } \
|
||||
inline Enum& operator&=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs & (__underlying_type(Enum))Rhs); } \
|
||||
inline Enum& operator^=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs ^ (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr Enum operator| (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs | (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr Enum operator& (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs & (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr Enum operator^ (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs ^ (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr bool operator! (Enum E) { return !(__underlying_type(Enum))E; } \
|
||||
inline constexpr Enum operator~ (Enum E) { return (Enum)~(__underlying_type(Enum))E; }
|
||||
@@ -99,14 +99,17 @@ DWORD WINAPI Main(LPVOID)
|
||||
static auto FortPlayerStateAthenaDefault = FindObject<AFortPlayerStateAthena>(L"/Script/FortniteGame.Default__FortPlayerStateAthena");
|
||||
static auto FortKismetLibraryDefault = FindObject<UFortKismetLibrary>(L"/Script/FortniteGame.Default__FortKismetLibrary");
|
||||
static auto AthenaMarkerComponentDefault = FindObject<UAthenaMarkerComponent>(L"/Script/FortniteGame.Default__AthenaMarkerComponent");
|
||||
static auto FortWeaponDefault = FindObject<AFortWeapon>(L"/Script/FortniteGame.Default__FortWeapon");
|
||||
|
||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogBuilding VeryVerbose", nullptr);
|
||||
// UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortUIDirector NoLogging", nullptr);
|
||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr);
|
||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFort VeryVerbose", nullptr);
|
||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogGameMode VeryVerbose", nullptr);
|
||||
|
||||
if (Globals::bNoMCP)
|
||||
{
|
||||
if (Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr))
|
||||
if (Fortnite_Version > 2.5 ? Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr) : true)
|
||||
{
|
||||
Hooking::MinHook::Hook((PVOID)Addresses::GetNetMode, (PVOID)GetNetModeHook, nullptr);
|
||||
}
|
||||
@@ -263,6 +266,9 @@ DWORD WINAPI Main(LPVOID)
|
||||
nullptr, false);
|
||||
}
|
||||
|
||||
Hooking::MinHook::Hook(FortWeaponDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortWeapon.ServerReleaseWeaponAbility"),
|
||||
AFortWeapon::ServerReleaseWeaponAbilityHook, (PVOID*)&AFortWeapon::ServerReleaseWeaponAbilityOriginal, false, true);
|
||||
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerDropAllItems"),
|
||||
AFortPlayerController::ServerDropAllItemsHook, nullptr, false);
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerAttemptInventoryDrop"),
|
||||
@@ -325,6 +331,8 @@ DWORD WINAPI Main(LPVOID)
|
||||
|
||||
// TODO Add RemoveItemFromInventoryOwner
|
||||
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.SpawnToyInstance"),
|
||||
AFortPlayerController::SpawnToyInstanceHook, (PVOID*)&AFortPlayerController::SpawnToyInstanceOriginal, false, true);
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.DropSpecificItem"),
|
||||
AFortPlayerController::DropSpecificItemHook, (PVOID*)&AFortPlayerController::DropSpecificItemOriginal, false, true);
|
||||
|
||||
@@ -438,6 +446,8 @@ DWORD WINAPI Main(LPVOID)
|
||||
Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal);
|
||||
Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf
|
||||
|
||||
if (Fortnite_Version >= 2.5)
|
||||
{
|
||||
auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)FindFunctionCall(L"ServerRemoveInventoryItem",
|
||||
Fortnite_Version >= 16 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C }), 0, true);
|
||||
|
||||
@@ -464,6 +474,7 @@ DWORD WINAPI Main(LPVOID)
|
||||
Memcury::Scanner(ServerRemoveInventoryItemFunctionCallBeginFunctionAddr).GetAs<PVOID>(),
|
||||
UFortInventoryInterface::RemoveInventoryItemHook
|
||||
);
|
||||
}
|
||||
|
||||
if (Fortnite_Version >= 13)
|
||||
Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal);
|
||||
|
||||
@@ -17,3 +17,13 @@ extern inline double Fortnite_Version = 0; // For example, 4.1, 6.21, etc. // Pr
|
||||
|
||||
#define MS_ALIGN(n) __declspec(align(n))
|
||||
#define FORCENOINLINE __declspec(noinline)
|
||||
|
||||
#define ENUM_CLASS_FLAGS(Enum) \
|
||||
inline Enum& operator|=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs | (__underlying_type(Enum))Rhs); } \
|
||||
inline Enum& operator&=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs & (__underlying_type(Enum))Rhs); } \
|
||||
inline Enum& operator^=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs ^ (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr Enum operator| (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs | (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr Enum operator& (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs & (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr Enum operator^ (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs ^ (__underlying_type(Enum))Rhs); } \
|
||||
inline constexpr bool operator! (Enum E) { return !(__underlying_type(Enum))E; } \
|
||||
inline constexpr Enum operator~ (Enum E) { return (Enum)~(__underlying_type(Enum))E; }
|
||||
Reference in New Issue
Block a user