quite a bit of stuff

This commit is contained in:
Milxnor
2023-03-05 14:01:15 -05:00
parent 3e2da1eedf
commit 472fbdb809
45 changed files with 1076 additions and 69 deletions

View File

@@ -4,10 +4,11 @@
#include "GameplayAbilitySpec.h"
struct PadHex18 { char Pad[0x18]; };
struct PadHexA8 { char Pad[0xA8]; };
struct PadHexB0 { char Pad[0xB0]; };
using FPredictionKey = PadHex18;
using FGameplayEventData = PadHexB0;
using FPredictionKey = PadHex18; // PadHex18;
using FGameplayEventData = PadHexA8; // PadHexB0;
class UAbilitySystemComponent : public UObject
{

View File

@@ -6,7 +6,7 @@ void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<vo
static auto ActivatableAbilitiesOffset = AbilitySystemComponent->GetOffset("ActivatableAbilities");
auto ActivatableAbilities = AbilitySystemComponent->GetPtr<FFastArraySerializer>(ActivatableAbilitiesOffset);
static auto ItemsOffset = 0x0108;
static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items");
auto Items = (TArray<__int64>*)(__int64(ActivatableAbilities) + ItemsOffset);
static auto SpecSize = FGameplayAbilitySpec::GetStructSize();
@@ -28,7 +28,7 @@ void InternalServerTryActivateAbility(UAbilitySystemComponent* AbilitySystemComp
auto Spec = AbilitySystemComponent->FindAbilitySpecFromHandle(Handle);
static auto CurrentOffset = 0x0000;
static auto CurrentOffset = FindOffsetStruct("/Script/GameplayAbilities.PredictionKey", "Current");
if (!Spec)
{

View File

@@ -27,4 +27,13 @@ void AActor::K2_DestroyActor()
static auto DestroyActorFn = FindObject<UFunction>("/Script/Engine.Actor.K2_DestroyActor");
this->ProcessEvent(DestroyActorFn);
}
FVector AActor::GetActorLocation()
{
static auto K2_GetActorLocationFn = FindObject<UFunction>("/Script/Engine.Actor.K2_GetActorLocation");
FVector ret;
this->ProcessEvent(K2_GetActorLocationFn, &ret);
return ret;
}

View File

@@ -8,6 +8,6 @@ public:
struct FTransform GetTransform();
AActor* GetOwner();
struct FVector GetActorLocation();
void K2_DestroyActor();
};

View File

@@ -23,8 +23,8 @@ public:
public:
inline InElementType At(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType at(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType& At(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType& at(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType* AtPtr(int i, int Size = sizeof(InElementType)) const { return (InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline int Num() const { return ArrayNum; }
@@ -37,18 +37,18 @@ public:
void Reserve(int Number, int Size = sizeof(InElementType))
{
LOG_INFO(LogDev, "ArrayNum {}", ArrayNum);
// LOG_INFO(LogDev, "ArrayNum {}", ArrayNum);
// Data = (InElementType*)FMemory::Realloc(Data, (ArrayMax = ArrayNum + Number) * Size, 0);
Data = /* (ArrayMax - ArrayNum) >= ArrayNum ? Data : */ (InElementType*)FMemory::Realloc(Data, (ArrayMax = Number + ArrayNum) * Size, 0);
}
FORCENOINLINE void ResizeGrow(int32 OldNum, int Size = sizeof(InElementType))
{
LOG_INFO(LogMemory, "FMemory::Realloc: {}", __int64(FMemory::Realloc));
// LOG_INFO(LogMemory, "FMemory::Realloc: {}", __int64(FMemory::Realloc));
ArrayMax = ArrayNum; // CalculateSlackGrow(/* ArrayNum */ OldNum, ArrayMax, Size);
// AllocatorInstance.ResizeAllocation(OldNum, ArrayMax, sizeof(ElementType));
LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size);
// LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size);
Data = (InElementType*)FMemory::Realloc(Data, ArrayMax * Size, 0);
}
@@ -84,7 +84,7 @@ public:
int Add(const InElementType& New, int Size = sizeof(InElementType))
{
LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax);
// LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax);
if ((ArrayNum + 1) > ArrayMax)
{

View File

@@ -15,7 +15,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext)
{
LOG_INFO(LogDev, "Befor3e");
// LOG_INFO(LogDev, "Befor3e");
auto BuildingSMActor = Cast<ABuildingSMActor>(BuildingActor);
auto PlayerController = Cast<AFortPlayerControllerAthena>(InstigatedBy);
@@ -42,7 +42,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
// auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGGetGameStateAthena);
UCurveTable* CurveTable = nullptr; // GameState->CurrentPlaylistInfo.BasePlaylist ? GameState->CurrentPlaylistInfo.BasePlaylist->ResourceRates.Get() : nullptr;
LOG_INFO(LogDev, "Before1");
// LOG_INFO(LogDev, "Before1");
if (!CurveTable)
CurveTable = FindObject<UCurveTable>("/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates");
@@ -50,13 +50,14 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
{
// auto curveMap = ((UDataTable*)CurveTable)->GetRowMap();
LOG_INFO(LogDev, "Before {}", __int64(CurveTable));
// LOG_INFO(LogDev, "Before {}", __int64(CurveTable));
float Out;
FString ContextString;
UDataTableFunctionLibrary::EvaluateCurveTableRow(CurveTable, BuildingResourceAmountOverride.RowName, 0, ContextString, nullptr, &Out);
EEvaluateCurveTableResult result;
UDataTableFunctionLibrary::EvaluateCurveTableRow(CurveTable, BuildingResourceAmountOverride.RowName, 0.f, ContextString, &result, &Out);
LOG_INFO(LogDev, "Out: {}", Out);
// LOG_INFO(LogDev, "Out: {}", Out);
auto DamageThatWillAffect = Damage;

View File

@@ -0,0 +1,8 @@
#pragma once
#include "BuildingSMActor.h"
class ABuildingContainer : public ABuildingSMActor
{
public:
};

View File

@@ -36,7 +36,7 @@ UObject* UClass::CreateDefaultObject()
return DefaultObject;
}
int UClass::GetPropertiesSize()
int UStruct::GetPropertiesSize()
{
return *(int*)(__int64(this) + Offsets::PropertiesSize);
}

View File

@@ -12,14 +12,14 @@ struct UField : UObject
class UStruct : public UField
{
public:
int GetPropertiesSize();
};
class UClass : public UStruct
{
public:
UObject* CreateDefaultObject();
int GetPropertiesSize();
};
class UFunction : public UStruct

View File

@@ -8,7 +8,7 @@ class UDataTable : public UObject
{
public:
template <typename RowDataType = uint8_t>
TMap<FName, RowDataType*> GetRowMap()
TMap<FName, RowDataType*>& GetRowMap()
{
static auto RowStructOffset = FindOffsetStruct("/Script/Engine.DataTable", "RowStruct");

View File

@@ -3,7 +3,7 @@
#include "reboot.h"
void UDataTableFunctionLibrary::EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY,
FString ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY)
const FString& ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY)
{
static auto fn = FindObject<UFunction>("/Script/Engine.DataTableFunctionLibrary.EvaluateCurveTableRow");
@@ -17,10 +17,10 @@ void UDataTableFunctionLibrary::EvaluateCurveTableRow(UCurveTable* CurveTable, F
DefaultClass->ProcessEvent(fn, &UDataTableFunctionLibrary_EvaluateCurveTableRow_Params);
if (OutResult)
*OutResult = wtf1;
*OutResult = UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutResult;
if (OutXY)
*OutXY = wtf;
*OutXY = UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutXY;
}
UClass* UDataTableFunctionLibrary::StaticClass()

View File

@@ -15,7 +15,7 @@ class UDataTableFunctionLibrary : public UObject
{
public:
static void EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY,
FString ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY);
const FString& ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY);
static UClass* StaticClass();
};

View File

@@ -4,9 +4,96 @@
#include "NetSerialization.h"
#include "FortPlayerControllerAthena.h"
#include "GameplayStatics.h"
#include "KismetStringLibrary.h"
#include "SoftObjectPtr.h"
#include "FortPickup.h"
#include "FortLootPackage.h"
#include "BuildingContainer.h"
static bool bFirstPlayerJoined = false;
enum class EDynamicFoundationEnabledState : uint8_t
{
Unknown = 0,
Enabled = 1,
Disabled = 2,
EDynamicFoundationEnabledState_MAX = 3
};
// Enum FortniteGame.EDynamicFoundationType
enum class EDynamicFoundationType : uint8_t
{
Static = 0,
StartEnabled_Stationary = 1,
StartEnabled_Dynamic = 2,
StartDisabled = 3,
EDynamicFoundationType_MAX = 4
};
void ShowFoundation(AActor* BuildingFoundation)
{
SetBitfield(BuildingFoundation->GetPtr<PlaceholderBitfield>("bServerStreamedInLevel"), 2, true);
static auto OnRep_ServerStreamedInLevelFn = FindObject<UFunction>("/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel");
BuildingFoundation->ProcessEvent(OnRep_ServerStreamedInLevelFn);
static auto DynamicFoundationRepDataOffset = BuildingFoundation->GetOffset("DynamicFoundationRepData", false);
if (DynamicFoundationRepDataOffset != 0)
{
auto DynamicFoundationRepData = BuildingFoundation->GetPtr(DynamicFoundationRepDataOffset);
static auto EnabledStateOffset = FindOffsetStruct("/Script/FortniteGame.DynamicBuildingFoundationRepData", "EnabledState");
*(EDynamicFoundationEnabledState*)(__int64(DynamicFoundationRepData) + EnabledStateOffset) = EDynamicFoundationEnabledState::Enabled;
static auto OnRep_DynamicFoundationRepDataFn = FindObject<UFunction>("/Script/FortniteGame.BuildingFoundation.OnRep_DynamicFoundationRepData");
BuildingFoundation->ProcessEvent(OnRep_DynamicFoundationRepDataFn);
}
static auto FoundationEnabledStateOffset = BuildingFoundation->GetOffset("FoundationEnabledState");
BuildingFoundation->Get<EDynamicFoundationEnabledState>(FoundationEnabledStateOffset) = EDynamicFoundationEnabledState::Enabled;
}
static void StreamLevel(std::string LevelName, FVector Location = {})
{
static auto BuildingFoundation3x3Class = FindObject<UClass>("/Script/FortniteGame.BuildingFoundation3x3");
FTransform Transform{};
Transform.Scale3D = { 1, 1, 1 };
Transform.Translation = Location;
auto BuildingFoundation = GetWorld()->SpawnActor<ABuildingSMActor>(BuildingFoundation3x3Class, Transform);
BuildingFoundation->InitializeBuildingActor(BuildingFoundation, nullptr, false);
static auto FoundationNameOffset = FindOffsetStruct("/Script/FortniteGame.BuildingFoundationStreamingData", "FoundationName");
static auto FoundationLocationOffset = FindOffsetStruct("/Script/FortniteGame.BuildingFoundationStreamingData", "FoundationLocation");
static auto StreamingDataOffset = BuildingFoundation->GetOffset("StreamingData");
static auto LevelToStreamOffset = BuildingFoundation->GetOffset("LevelToStream");
auto StreamingData = BuildingFoundation->GetPtr<__int64>(StreamingDataOffset);
*(FName*)(__int64(StreamingData) + FoundationNameOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str());
*(FVector*)(__int64(StreamingData) + FoundationLocationOffset) = Location;
*(FName*)(__int64(BuildingFoundation) + LevelToStreamOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str());
static auto OnRep_LevelToStreamFn = FindObject<UFunction>("/Script/FortniteGame.BuildingFoundation.OnRep_LevelToStream");
BuildingFoundation->ProcessEvent(OnRep_LevelToStreamFn);
ShowFoundation(BuildingFoundation);
}
UObject* GetPlaylistToUse()
{
auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo");
if (Globals::bCreative)
Playlist = FindObject("/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2");
return Playlist;
}
bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode)
{
auto GameState = GameMode->GetGameStateAthena();
@@ -18,9 +105,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static auto PlaylistReplicationKeyOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "PlaylistReplicationKey");
static auto BasePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "BasePlaylist");
static auto OverridePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "OverridePlaylist");
*(UObject**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset) = Playlist;
// CurrentPlaylistInfo.OverridePlaylist = Playlist;
*(UObject**)(__int64(CurrentPlaylistInfo) + OverridePlaylistOffset) = Playlist;
(*(int*)(__int64(CurrentPlaylistInfo) + PlaylistReplicationKeyOffset))++;
CurrentPlaylistInfo->MarkArrayDirty();
@@ -30,7 +118,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
else
{
GameState->Get("CurrentPlaylistData") = Playlist;
GameState->OnRep_CurrentPlaylistInfo();
GameState->OnRep_CurrentPlaylistInfo(); // calls OnRep_CurrentPlaylistData
}
};
@@ -47,12 +135,22 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
{
LastNum2 = AmountOfRestarts;
auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo");
// SetPlaylist(Playlist);
GameMode->Get<int>("WarmupRequiredPlayerCount") = 1;
auto PlaylistToUse = GetPlaylistToUse();
GameMode->Get<int>("WarmupRequiredPlayerCount") = 1;
if (PlaylistToUse)
{
static auto AdditionalLevelsOffset = PlaylistToUse->GetOffset("AdditionalLevels");
auto& AdditionalLevels = PlaylistToUse->Get<TArray<TSoftObjectPtr<UClass>>>(AdditionalLevelsOffset);
// LOG_INFO(LogLoading, "Set playlist!");
for (int i = 0; i < AdditionalLevels.Num(); i++)
{
// auto World = Cast<UWorld>(Playlist->AdditionalLevels[i].Get());
// StreamLevel(UKismetSystemLibrary::GetPathName(World->PersistentLevel).ToString());
StreamLevel(AdditionalLevels.at(i).SoftObjectPtr.ObjectID.AssetPathName.ToString());
}
}
}
/* static auto FortPlayerStartWarmupClass = FindObject<UClass>("/Script/FortniteGame.FortPlayerStartWarmup");
@@ -122,9 +220,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
GameState->OnRep_GamePhase();
}
auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo");
// FindObject("/Game/Athena/Playlists/Playground/Playlist_Playground.Playlist_Playground");
SetPlaylist(Playlist);
SetPlaylist(GetPlaylistToUse());
GameState->Get<float>("WarmupCountdownEndTime") = TimeSeconds + Duration;
GameMode->Get<float>("WarmupCountdownDuration") = Duration;
@@ -151,8 +247,87 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
return ++NextTeamIndex;
}
enum class EFortCustomPartType : uint8_t // todo move
{
Head = 0,
Body = 1,
Hat = 2,
Backpack = 3,
Charm = 4,
Face = 5,
NumTypes = 6,
EFortCustomPartType_MAX = 7
};
void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor)
{
auto SpawnIsland_FloorLoot = FindObject<UClass>("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_Warmup.Tiered_Athena_FloorLoot_Warmup_C");
auto BRIsland_FloorLoot = FindObject<UClass>("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_01.Tiered_Athena_FloorLoot_01_C");
TArray<AActor*> SpawnIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), SpawnIsland_FloorLoot);
TArray<AActor*> BRIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BRIsland_FloorLoot);
auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup");
auto BRIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot");
float UpZ = 50;
EFortPickupSourceTypeFlag SpawnFlag = EFortPickupSourceTypeFlag::Container;
bool bPrintWarmup = false;
for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); i++)
{
ABuildingContainer* CurrentActor = (ABuildingContainer*)SpawnIsland_FloorLoot_Actors.at(i);
// CurrentActor->K2_DestroyActor();
// continue;
auto Location = CurrentActor->GetActorLocation();
Location.Z += UpZ;
std::vector<std::pair<UFortItemDefinition*, int>> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup);
if (bPrintWarmup)
{
std::cout << "\n\n";
}
if (LootDrops.size())
{
for (auto& LootDrop : LootDrops)
AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag);
}
}
bool bPrint = false;
int spawned = 0;
for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++)
{
ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i);
// CurrentActor->K2_DestroyActor();
spawned++;
// continue;
auto Location = CurrentActor->GetActorLocation();
Location.Z += UpZ;
std::vector<std::pair<UFortItemDefinition*, int>> LootDrops = PickLootDrops(BRIslandTierGroup, bPrint);
if (bPrint)
std::cout << "\n";
if (LootDrops.size())
{
for (auto& LootDrop : LootDrops)
AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag);
}
}
auto GameState = GameMode->GetGameStateAthena();
auto NewPlayer = (AFortPlayerControllerAthena*)NewPlayerActor;
@@ -179,6 +354,25 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
auto PlayerStateAthena = NewPlayer->GetPlayerStateAthena();
static auto CharacterPartsOffset = PlayerStateAthena->GetOffset("CharacterParts", false);
if (CharacterPartsOffset != 0)
{
auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts");
static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts");
auto Parts = (UObject**)(__int64(CharacterParts) + PartsOffset); // UCustomCharacterPart* Parts[0x6]
static auto headPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Heads/F_Med_Head1.F_Med_Head1");
static auto bodyPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Bodies/F_Med_Soldier_01.F_Med_Soldier_01");
Parts[(int)EFortCustomPartType::Head] = headPart;
Parts[(int)EFortCustomPartType::Body] = bodyPart;
static auto OnRep_CharacterPartsFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts");
PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn);
}
PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2;
// if (false)
@@ -200,9 +394,11 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
if (false)
{
static auto GameplayAbilitySet = FindObject<UObject>("/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") ?
FindObject<UObject>("/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") :
FindObject<UObject>("/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer");
static auto GameplayAbilitySet = LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") ?
LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") :
LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer");
// LOG_INFO(LogDev, "GameplayAbilitySet {}", __int64(GameplayAbilitySet));
if (GameplayAbilitySet)
{
@@ -213,7 +409,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
{
UClass* AbilityClass = GameplayAbilities->At(i);
LOG_INFO(LogDev, "AbilityClass {}", __int64(AbilityClass));
// LOG_INFO(LogDev, "AbilityClass {}", __int64(AbilityClass));
if (!AbilityClass)
continue;

View File

@@ -33,7 +33,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
static auto FortItemEntrySize = *(int*)(__int64(FortItemEntryStruct) + Offsets::PropertiesSize);
// LOG_INFO(LogDev, "FortItemEntryStruct {}", __int64(FortItemEntryStruct));
LOG_INFO(LogDev, "FortItemEntrySize {}", __int64(FortItemEntrySize));
// LOG_INFO(LogDev, "FortItemEntrySize {}", __int64(FortItemEntrySize));
GetItemList().GetItemInstances().Add(NewItemInstance);
GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FortItemEntrySize);

View File

@@ -18,6 +18,18 @@ struct FFortItemEntry : FFastArraySerializerItem
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ItemDefinition");
return *(UObject**)(__int64(this) + ItemDefinitionOffset);
}
int& GetCount()
{
static auto CountOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "Count");
return *(int*)(__int64(this) + CountOffset);
}
int& GetLoadedAmmo()
{
static auto LoadedAmmoOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "LoadedAmmo");
return *(int*)(__int64(this) + LoadedAmmoOffset);
}
};
class UFortItem : public UObject

View File

@@ -8,4 +8,16 @@ UFortItem* UFortItemDefinition::CreateTemporaryItemInstanceBP(int Count, int Lev
ProcessEvent(CreateTemporaryItemInstanceBPFunction, &CreateTemporaryItemInstanceBP_Params);
return CreateTemporaryItemInstanceBP_Params.ReturnValue;
}
float UFortItemDefinition::GetMaxStackSize()
{
static auto MaxStackSizeOffset = this->GetOffset("MaxStackSize");
bool bIsScalableFloat = false;
if (!bIsScalableFloat)
return Get<int>(MaxStackSizeOffset);
return 0;
}

View File

@@ -10,4 +10,5 @@ class UFortItemDefinition : public UObject
{
public:
UFortItem* CreateTemporaryItemInstanceBP(int Count, int Level = 1);
float GetMaxStackSize();
};

View File

@@ -0,0 +1,330 @@
#include "FortLootPackage.h"
#include "DataTable.h"
#include "KismetMathLibrary.h"
static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootTierData, bool bPrint)
{
float TotalWeight = 0;
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);
}
for (auto Item : LootTierData)
{
if (bPrint)
{
std::cout << std::format("Rand: {} Weight: {}\n", RandomNumber, Item->GetWeight());
}
if (RandomNumber <= Item->GetWeight())
{
SelectedItem = Item;
break;
}
RandomNumber -= Item->GetWeight();
}
if (!SelectedItem)
return GetLootTierData(LootTierData, bPrint);
return SelectedItem;
}
static FFortLootPackageData* GetLootPackage(std::vector<FFortLootPackageData*>& LootPackages)
{
float TotalWeight = 0;
for (auto Item : LootPackages)
{
TotalWeight += Item->GetWeight();
}
float RandomNumber = UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
FFortLootPackageData* SelectedItem = nullptr;
for (auto Item : LootPackages)
{
if (RandomNumber <= Item->GetWeight())
{
SelectedItem = Item;
break;
}
RandomNumber -= Item->GetWeight();
}
if (!SelectedItem)
return GetLootPackage(LootPackages);
return SelectedItem;
}
std::vector<std::pair<UFortItemDefinition*, int>> PickLootDrops(FName TierGroupName, bool bPrint, int recursive)
{
std::vector<std::pair<UFortItemDefinition*, int>> LootDrops;
static std::vector<UDataTable*> LTDTables;
static std::vector<UDataTable*> LPTables;
static bool bHasFoundTables = false;
if (!bHasFoundTables)
{
bHasFoundTables = true;
LTDTables.push_back(FindObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"));
LPTables.push_back(FindObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client"));
}
std::vector<FFortLootTierData*> TierGroupLTDs;
for (int p = 0; p < LTDTables.size(); p++)
{
auto LTD = LTDTables[p];
auto& LTDRowMap = LTD->GetRowMap();
auto LTDRowMapNum = LTDRowMap.Pairs.Elements.Num();
// auto TierGroupNameStr = TierGroupName.ToString();
for (int i = 0; i < LTDRowMapNum; i++)
{
auto& CurrentLTD = LTDRowMap.Pairs.Elements[i].ElementData.Value;
auto TierData = (FFortLootTierData*)CurrentLTD.Value();
// auto TierDataGroupStr = TierData->TierGroup.ToString();
// std::cout << "TierData->TierGroup.ToString(): " << TierDataGroupStr << '\n';
if (TierGroupName == TierData->GetTierGroup() /* TierDataGroupStr == TierGroupNameStr */ && TierData->GetWeight() != 0)
{
TierGroupLTDs.push_back(TierData);
}
}
}
if (TierGroupLTDs.size() == 0)
{
// std::cout << "Failed to find LTD!\n";
std::cout << "Failed to find any LTD for: " << TierGroupName.ToString() << '\n';
return LootDrops;
}
if (bPrint)
{
std::cout << "TierGroupLTDs.size(): " << TierGroupLTDs.size() << '\n';
}
FFortLootTierData* ChosenRowLootTierData = GetLootTierData(TierGroupLTDs, bPrint);
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;
float NumLootPackageDrops = std::floor(ChosenRowLootTierData->GetNumLootPackageDrops());
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];
auto& LPRowMap = LP->GetRowMap();
for (int i = 0; i < LPRowMap.Pairs.Elements.Num(); i++)
{
auto& CurrentLP = LPRowMap.Pairs.Elements[i].ElementData.Value;
auto LootPackage = (FFortLootPackageData*)CurrentLP.Value();
if (!LootPackage)
continue;
if (LootPackage->GetLootPackageID() == ChosenRowLootTierData->GetLootPackage() && LootPackage->GetWeight() != 0)
{
TierGroupLPs.push_back(LootPackage);
}
}
}
auto ChosenLootPackageName = ChosenRowLootTierData->GetLootPackage().ToString();
if (ChosenLootPackageName.contains(".Empty"))
{
return PickLootDrops(TierGroupName, bPrint);
// return LootDrops;
}
bool bIsWorldList = ChosenLootPackageName.contains("WorldList");
if (bPrint)
{
std::cout << "NumLootPackageDrops Floored: " << NumLootPackageDrops << '\n';
std::cout << "NumLootPackageDrops Original: " << ChosenRowLootTierData->GetNumLootPackageDrops() << '\n';
std::cout << "TierGroupLPs.size(): " << TierGroupLPs.size() << '\n';
std::cout << "ChosenLootPackageName: " << ChosenLootPackageName << '\n';
/* 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++)
{
if (i >= TierGroupLPs.size())
break;
auto TierGroupLP = TierGroupLPs.at(i);
auto TierGroupLPStr = TierGroupLP->GetLootPackageCall().ToString();
if (TierGroupLPStr.contains(".Empty"))
{
NumLootPackageDrops++;
continue;
}
std::vector<FFortLootPackageData*> lootPackageCalls;
if (bIsWorldList)
{
for (int j = 0; j < TierGroupLPs.size(); j++)
{
auto& CurrentLP = TierGroupLPs.at(j);
if (CurrentLP->GetWeight() != 0)
lootPackageCalls.push_back(CurrentLP);
}
}
else
{
for (int p = 0; p < LPTables.size(); p++)
{
auto LPRowMap = LPTables[p]->GetRowMap();
for (int j = 0; j < LPRowMap.Pairs.Elements.Num(); j++)
{
auto& CurrentLP = LPRowMap.Pairs.Elements[j].ElementData.Value;
auto LootPackage = (FFortLootPackageData*)CurrentLP.Value();
if (LootPackage->GetLootPackageID().ToString() == TierGroupLPStr && LootPackage->GetWeight() != 0)
{
lootPackageCalls.push_back(LootPackage);
}
}
}
}
if (lootPackageCalls.size() == 0)
{
// std::cout << "lootPackageCalls.size() == 0!\n";
NumLootPackageDrops++; // ??
continue;
}
FFortLootPackageData* LootPackageCall = GetLootPackage(lootPackageCalls);
if (!LootPackageCall) // Should NEVER happen
continue;
auto ItemDef = LootPackageCall->GetItemDefinition().Get();
if (!ItemDef)
{
NumLootPackageDrops++; // ??
continue;
}
if (bPrint)
{
std::cout << std::format("[{}] {} {} {}\n", i, lootPackageCalls.size(), TierGroupLPStr, ItemDef->GetName());
}
LootDrops.push_back({ ItemDef, LootPackageCall->GetCount() });
}
return LootDrops;
}

View File

@@ -0,0 +1,89 @@
#pragma once
#include <vector>
#include "Array.h"
#include "FortItemDefinition.h"
#include "SoftObjectPtr.h"
struct FFortLootPackageData
{
public:
FName& GetLootPackageID()
{
static auto LootPackageIDOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "LootPackageID");
return *(FName*)(__int64(this) + LootPackageIDOffset);
}
float& GetWeight()
{
static auto WeightOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Weight");
return *(float*)(__int64(this) + WeightOffset);
}
FString& GetLootPackageCall()
{
static auto LootPackageCallOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "LootPackageCall");
return *(FString*)(__int64(this) + LootPackageCallOffset);
}
TSoftObjectPtr<UFortItemDefinition>& GetItemDefinition()
{
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "ItemDefinition");
return *(TSoftObjectPtr<UFortItemDefinition>*)(__int64(this) + ItemDefinitionOffset);
}
int& GetCount()
{
static auto CountOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Count");
return *(int*)(__int64(this) + CountOffset);
}
};
struct FFortLootTierData
{
public:
float& GetNumLootPackageDrops()
{
static auto NumLootPackageDropsOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "NumLootPackageDrops");
return *(float*)(__int64(this) + NumLootPackageDropsOffset);
}
FName& GetTierGroup()
{
static auto TierGroupOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "TierGroup");
return *(FName*)(__int64(this) + TierGroupOffset);
}
float& GetWeight()
{
static auto WeightOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "Weight");
return *(float*)(__int64(this) + WeightOffset);
}
FName& GetLootPackage()
{
static auto LootPackageOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackage");
return *(FName*)(__int64(this) + LootPackageOffset);
}
TArray<int>& GetLootPackageCategoryWeightArray()
{
static auto LootPackageCategoryWeightArrayOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackageCategoryWeightArray");
return *(TArray<int>*)(__int64(this) + LootPackageCategoryWeightArrayOffset);
}
TArray<int>& GetLootPackageCategoryMinArray()
{
static auto LootPackageCategoryMinArrayOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackageCategoryMinArray");
return *(TArray<int>*)(__int64(this) + LootPackageCategoryMinArrayOffset);
}
TArray<int>& GetLootPackageCategoryMaxArray()
{
static auto LootPackageCategoryMaxArrayOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackageCategoryMaxArray");
return *(TArray<int>*)(__int64(this) + LootPackageCategoryMaxArrayOffset);
}
};
std::vector<std::pair<UFortItemDefinition*, int>> PickLootDrops(FName TierGroupName, bool bPrint = false, int recursive = 0);

View File

@@ -0,0 +1,58 @@
#include "FortPickup.h"
#include "FortPawn.h"
#include "FortItemDefinition.h"
#include "FortPlayerState.h"
void AFortPickup::TossPickup(FVector FinalLocation, AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, EFortPickupSourceTypeFlag InPickupSourceTypeFlags, EFortPickupSpawnSource InPickupSpawnSource)
{
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.FortPickup.TossPickup");
struct { FVector FinalLocation; AFortPawn* ItemOwner; int OverrideMaxStackCount; bool bToss;
EFortPickupSourceTypeFlag InPickupSourceTypeFlags; EFortPickupSpawnSource InPickupSpawnSource; }
AFortPickup_TossPickup_Params{FinalLocation, ItemOwner, OverrideMaxStackCount, bToss, InPickupSourceTypeFlags, InPickupSpawnSource};
this->ProcessEvent(fn, &AFortPickup_TossPickup_Params);
}
AFortPickup* AFortPickup::SpawnPickup(UFortItemDefinition* ItemDef, FVector Location, int Count, EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource, int LoadedAmmo, AFortPawn* Pawn)
{
static auto FortPickupClass = FindObject<UClass>(L"/Script/FortniteGame.FortPickup");
// auto PlayerState = Pawn ? Cast<AFortPlayerState>(Pawn->GetPlayerState) : nullptr;
if (auto Pickup = GetWorld()->SpawnActor<AFortPickup>(FortPickupClass, Location))
{
static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup");
static auto PrimaryPickupItemEntryOffset = Pickup->GetOffset("PrimaryPickupItemEntry");
auto PrimaryPickupItemEntry = Pickup->GetPtr<FFortItemEntry>(PrimaryPickupItemEntryOffset);
PrimaryPickupItemEntry->GetCount() = Count;
PrimaryPickupItemEntry->GetItemDefinition() = ItemDef;
PrimaryPickupItemEntry->GetLoadedAmmo() = LoadedAmmo;
// Pickup->OptionalOwnerID = Pawn ? PlayerState->WorldPlayerId : -1;
Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset) = Pawn;
// Pickup->bCombinePickupsWhenTossCompletes = true;
bool bToss = true;
if (bToss)
{
PickupSource |= EFortPickupSourceTypeFlag::Tossed;
}
Pickup->TossPickup(Location, Pawn, 0, bToss, PickupSource, SpawnSource);
if (PickupSource == EFortPickupSourceTypeFlag::Container)
{
static auto bTossedFromContainerOffset = Pickup->GetOffset("bTossedFromContainer");
Pickup->Get<bool>(bTossedFromContainerOffset) = true;
// Pickup->OnRep_TossedFromContainer();
} // crashes if we do this then tosspickup
return Pickup;
}
return nullptr;
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include "Actor.h"
enum class EFortPickupSourceTypeFlag : uint8_t
{
Other = 0,
Player = 1,
Destruction = 2,
Container = 3,
AI = 4,
Tossed = 5,
FloorLoot = 6,
EFortPickupSourceTypeFlag_MAX = 7
};
enum class EFortPickupSpawnSource : uint8_t
{
Unset = 0,
PlayerElimination = 1,
Chest = 2,
SupplyDrop = 3,
AmmoBox = 4,
Drone = 5,
ItemSpawner = 6,
EFortPickupSpawnSource_MAX = 7
};
ENUM_CLASS_FLAGS(EFortPickupSourceTypeFlag)
class AFortPickup : public AActor
{
public:
void TossPickup(FVector FinalLocation, class AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, EFortPickupSourceTypeFlag InPickupSourceTypeFlags, EFortPickupSpawnSource InPickupSpawnSource);
static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count,
EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset,
int LoadedAmmo = -1, class AFortPawn* Pawn = nullptr);
};

View File

@@ -26,7 +26,6 @@ public:
return Get<AFortPawn*>(MyFortPawnOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController");

View File

@@ -20,19 +20,21 @@ struct FGameplayAbilitySpec : FFastArraySerializerItem
{
static int GetStructSize()
{
static auto StructSize = 0x00C8;
static auto GameplayAbilitySpecStruct = FindObject<UClass>("/Script/GameplayAbilities.GameplayAbilitySpec");
static auto StructSize = GameplayAbilitySpecStruct->GetPropertiesSize();
// *(int*)(__int64(GameplayAbilitySpecStruct) + Offsets::PropertiesSize);
return StructSize;
}
UObject*& GetAbility()
{
static auto AbilityOffset = 0x0010;
static auto AbilityOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Ability");
return *(UObject**)(__int64(this) + AbilityOffset);
}
FGameplayAbilitySpecHandle& GetHandle()
{
static auto HandleOffset = 0xC;
static auto HandleOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Handle");
return *(FGameplayAbilitySpecHandle*)(__int64(this) + HandleOffset);
}
};
@@ -44,11 +46,9 @@ static FGameplayAbilitySpec* MakeNewSpec(UClass* GameplayAbilityClass, UObject*
if (!NewSpec)
return nullptr;
static auto HandleOffset = 0xC;
static auto AbilityOffset = 0x0010;
static auto LevelOffset = 0x0018;
static auto InputIDOffset = 0x001C;
static auto SourceObjectOffset = 0x0020;
static auto LevelOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Level");
static auto SourceObjectOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "SourceObject");
static auto InputIDOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "InputID");
((FFastArraySerializerItem*)NewSpec)->MostRecentArrayReplicationKey = -1;
((FFastArraySerializerItem*)NewSpec)->ReplicationID = -1;

View File

@@ -6,15 +6,13 @@ TArray<AActor*> UGameplayStatics::GetAllActorsOfClass(const UObject* WorldContex
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.GameplayStatics.GetAllActorsOfClass");
TArray<AActor*> ahh;
struct { const UObject* WorldContextObject; UClass* ActorClass; TArray<AActor*> OutActors; }
UGameplayStatics_GetAllActorsOfClass_Params{ WorldContextObject, ActorClass, ahh };
UGameplayStatics_GetAllActorsOfClass_Params{ WorldContextObject, ActorClass };
static auto defaultObj = StaticClass();
defaultObj->ProcessEvent(fn, &UGameplayStatics_GetAllActorsOfClass_Params);
return ahh;
return UGameplayStatics_GetAllActorsOfClass_Params.OutActors;
}
float UGameplayStatics::GetTimeSeconds(const UObject* WorldContextObject)

View File

@@ -0,0 +1,21 @@
#include "KismetMathLibrary.h"
#include "reboot.h"
float UKismetMathLibrary::RandomFloatInRange(float min, float max)
{
static auto fn = FindObject<UFunction>("/Script/Engine.KismetMathLibrary.RandomFloatInRange");
struct { float min; float max; float ret; } params{min, max};
static auto DefaultObject = StaticClass();
DefaultObject->ProcessEvent(fn, &params);
return params.ret;
}
UClass* UKismetMathLibrary::StaticClass()
{
static auto Class = FindObject<UClass>("/Script/Engine.KismetMathLibrary");
return Class;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Object.h"
class UKismetMathLibrary : public UObject
{
public:
static float RandomFloatInRange(float min, float max);
static UClass* StaticClass();
};

View File

@@ -11,6 +11,23 @@ class TPair
public:
KeyType First;
ValueType Second;
FORCEINLINE KeyType& Key()
{
return First;
}
FORCEINLINE const KeyType& Key() const
{
return First;
}
FORCEINLINE ValueType& Value()
{
return Second;
}
FORCEINLINE const ValueType& Value() const
{
return Second;
}
};
template <typename KeyType, typename ValueType> //, typename SetAllocator, typename KeyFuncs>

View File

@@ -15,4 +15,9 @@ struct FName
std::string ToString();
bool IsValid() { return ComparisonIndex.Value > 0; }
bool operator==(FName other)
{
return ComparisonIndex.Value == other.ComparisonIndex.Value;
}
};

View File

@@ -72,3 +72,9 @@ bool UObject::IsA(UClass* otherClass)
return false;
}
class UClass* UObject::StaticClass()
{
static auto Class = FindObject<UClass>("/Script/CoreUObject.Object");
return Class;
}

View File

@@ -80,4 +80,6 @@ public:
template <typename T = UObject*>
T* GetPtr(const std::string& ChildName) { return GetPtr<T>(GetOffset(ChildName)); }
static class UClass* StaticClass();
};

View File

@@ -0,0 +1,15 @@
#pragma once
#include "WeakObjectPtr.h"
template<class TObjectID>
struct TPersistentObjectPtr
{
public:
/** Once the object has been noticed to be loaded, this is set to the object weak pointer **/
mutable FWeakObjectPtr WeakPtr;
/** Compared to CurrentAnnotationTag and if they are not equal, a guid search will be performed **/
mutable int TagAtLastTest;
/** Guid for the object this pointer points to or will point to. **/
TObjectID ObjectID;
};

View File

@@ -184,10 +184,12 @@
<ClCompile Include="FortKismetLibrary.cpp" />
<ClCompile Include="FortLootPackage.cpp" />
<ClCompile Include="FortPawn.cpp" />
<ClCompile Include="FortPickup.cpp" />
<ClCompile Include="FortPlayerController.cpp" />
<ClCompile Include="FortWeapon.cpp" />
<ClCompile Include="GameModeBase.cpp" />
<ClCompile Include="GameplayStatics.cpp" />
<ClCompile Include="KismetMathLibrary.cpp" />
<ClCompile Include="KismetStringLibrary.cpp" />
<ClCompile Include="LevelActor.cpp" />
<ClCompile Include="NameTypes.cpp" />
@@ -207,6 +209,7 @@
<ClInclude Include="Array.h" />
<ClInclude Include="BitArray.h" />
<ClInclude Include="BuildingActor.h" />
<ClInclude Include="BuildingContainer.h" />
<ClInclude Include="BuildingSMActor.h" />
<ClInclude Include="Class.h" />
<ClInclude Include="ContainerAllocationPolicies.h" />
@@ -227,6 +230,7 @@
<ClInclude Include="FortKismetLibrary.h" />
<ClInclude Include="FortLootPackage.h" />
<ClInclude Include="FortPawn.h" />
<ClInclude Include="FortPickup.h" />
<ClInclude Include="FortPlayerController.h" />
<ClInclude Include="FortPlayerControllerAthena.h" />
<ClInclude Include="FortPlayerState.h" />
@@ -246,6 +250,7 @@
<ClInclude Include="GameState.h" />
<ClInclude Include="hooking.h" />
<ClInclude Include="inc.h" />
<ClInclude Include="KismetMathLibrary.h" />
<ClInclude Include="KismetStringLibrary.h" />
<ClInclude Include="KismetSystemLibrary.h" />
<ClInclude Include="log.h" />
@@ -257,6 +262,7 @@
<ClInclude Include="ObjectMacros.h" />
<ClInclude Include="OutputDevice.h" />
<ClInclude Include="Pawn.h" />
<ClInclude Include="PersistentObjectPtr.h" />
<ClInclude Include="PlayerController.h" />
<ClInclude Include="PlayerState.h" />
<ClInclude Include="Quat.h" />
@@ -264,6 +270,8 @@
<ClInclude Include="Rotator.h" />
<ClInclude Include="ScriptInterface.h" />
<ClInclude Include="Set.h" />
<ClInclude Include="SoftObjectPath.h" />
<ClInclude Include="SoftObjectPtr.h" />
<ClInclude Include="SparseArray.h" />
<ClInclude Include="Stack.h" />
<ClInclude Include="Transform.h" />
@@ -272,6 +280,7 @@
<ClInclude Include="UObjectArray.h" />
<ClInclude Include="UObjectGlobals.h" />
<ClInclude Include="Vector.h" />
<ClInclude Include="WeakObjectPtr.h" />
<ClInclude Include="World.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -101,6 +101,12 @@
<ClCompile Include="DataTableFunctionLibrary.cpp">
<Filter>Engine\Source\Runtime\Engine\Private</Filter>
</ClCompile>
<ClCompile Include="KismetMathLibrary.cpp">
<Filter>Engine\Source\Runtime\Engine\Private</Filter>
</ClCompile>
<ClCompile Include="FortPickup.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private\Items</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="log.h" />
@@ -314,6 +320,27 @@
<ClInclude Include="DataTableFunctionLibrary.h">
<Filter>Engine\Source\Runtime\Engine\Classes\Kismet</Filter>
</ClInclude>
<ClInclude Include="SoftObjectPtr.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="PersistentObjectPtr.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="WeakObjectPtr.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="SoftObjectPath.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="KismetMathLibrary.h">
<Filter>Engine\Source\Runtime\Engine\Classes\Kismet</Filter>
</ClInclude>
<ClInclude Include="FortPickup.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Items</Filter>
</ClInclude>
<ClInclude Include="BuildingContainer.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Engine">
@@ -412,9 +439,6 @@
<Filter Include="FortniteGame\Source\FortniteGame\Public\Pawns">
<UniqueIdentifier>{4f177a72-585d-4b79-a258-26bb6d2c225c}</UniqueIdentifier>
</Filter>
<Filter Include="FortniteGame\Source\FortniteGame\Public\Weapons">
<UniqueIdentifier>{bcb0d983-0b85-4ca6-9fac-6567c7d79921}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\Plugins">
<UniqueIdentifier>{826a509f-03f4-4a18-a9bf-d67b69fe3b93}</UniqueIdentifier>
</Filter>
@@ -466,6 +490,9 @@
<Filter Include="Engine\Source\Runtime\Core\Public\Templates">
<UniqueIdentifier>{31a7f342-8b7c-4594-a24d-c4dd5c9d230d}</UniqueIdentifier>
</Filter>
<Filter Include="FortniteGame\Source\FortniteGame\Public\Weapons">
<UniqueIdentifier>{bcb0d983-0b85-4ca6-9fac-6567c7d79921}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="UnrealEngine.cpp">

View File

@@ -35,6 +35,7 @@ public:
template<typename InElementType> //, typename KeyFuncs, typename Allocator>
class TSet
{
public:
typedef TSetElement<InElementType> ElementType;
typedef TSparseArrayElementOrListLink<ElementType> ArrayElementType;

View File

@@ -0,0 +1,14 @@
#pragma once
#include "NameTypes.h"
#include "UnrealString.h"
struct FSoftObjectPath
{
public:
/** Asset path, patch to a top level object in a package. This is /package/path.assetname */
FName AssetPathName;
/** Optional FString for subobject within an asset. This is the sub path after the : */
FString SubPathString;
};

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Object.h"
#include "PersistentObjectPtr.h"
#include "SoftObjectPath.h"
#include "reboot.h"
struct FSoftObjectPtr : public TPersistentObjectPtr<FSoftObjectPath>
{
public:
};
template<class T = UObject>
struct TSoftObjectPtr
{
public:
FSoftObjectPtr SoftObjectPtr;
T* Get()
{
return FindObject<T>(SoftObjectPtr.ObjectID.AssetPathName.ToString());
}
};

View File

@@ -49,4 +49,18 @@ public:
TBitArray AllocationFlags;
int32 FirstFreeIndex;
int32 NumFreeIndices;
FORCEINLINE FSparseArrayElement& operator[](uint32 Index)
{
return *(FSparseArrayElement*)&Data.at(Index).ElementData;
}
FORCEINLINE const FSparseArrayElement& operator[](uint32 Index) const
{
return *(const FSparseArrayElement*)&Data.at(Index).ElementData;
}
FORCEINLINE int32 Num() const
{
return Data.Num() - NumFreeIndices;
}
};

View File

@@ -2,9 +2,11 @@
#include "Object.h"
#define ANY_PACKAGE (UObject*)-1
extern inline UObject* (*StaticFindObjectOriginal)(UClass* Class, UObject* InOuter, const TCHAR* Name, bool ExactClass) = nullptr;
template <typename T>
template <typename T = UObject>
static inline T* StaticFindObject(UClass* Class, UObject* InOuter, const TCHAR* Name, bool ExactClass = false)
{
// LOG_INFO(LogDev, "StaticFindObjectOriginal: {}", __int64(StaticFindObjectOriginal));

View File

@@ -0,0 +1,8 @@
#pragma once
struct FWeakObjectPtr
{
public:
int ObjectIndex;
int ObjectSerialNumber;
};

View File

@@ -3,6 +3,7 @@
#include "EngineTypes.h"
#include "Transform.h"
#include "Object.h"
#include "Rotator.h"
struct FNetworkNotify
{
@@ -45,5 +46,15 @@ public:
return (ActorType*)SpawnActorOriginal(this, Class, &UserTransformPtr, SpawnParameters);
}
template <typename ActorType>
ActorType* SpawnActor(UClass* Class, FVector Location, FQuat Rotation = FQuat(), FVector Scale3D = FVector(1, 1, 1), const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters())
{
FTransform UserTransformPtr{};
UserTransformPtr.Translation = Location;
UserTransformPtr.Rotation = Rotation;
UserTransformPtr.Scale3D = Scale3D;
return SpawnActor<ActorType>(Class, UserTransformPtr, SpawnParameters);
}
void Listen();
};

View File

@@ -130,6 +130,7 @@ void Addresses::FindAll()
Addresses::ReplaceBuildingActor = FindReplaceBuildingActor();
Addresses::GiveAbilityAndActivateOnce = FindGiveAbilityAndActivateOnce();
Addresses::OnDamageServer = FindOnDamageServer();
Addresses::StaticLoadObject = FindStaticLoadObject();
}
void Addresses::Print()
@@ -159,6 +160,7 @@ void Addresses::Print()
LOG_INFO(LogDev, "ReplaceBuildingActor: 0x{:x}", ReplaceBuildingActor - Base);
LOG_INFO(LogDev, "GiveAbilityAndActivateOnce: 0x{:x}", GiveAbilityAndActivateOnce - Base);
LOG_INFO(LogDev, "OnDamageServer: 0x{:x}", OnDamageServer - Base);
LOG_INFO(LogDev, "StaticLoadObject: 0x{:x}", StaticLoadObject - Base);
}
void Offsets::FindAll()
@@ -222,6 +224,7 @@ void Addresses::Init()
UAbilitySystemComponent::GiveAbilityOriginal = decltype(UAbilitySystemComponent::GiveAbilityOriginal)(GiveAbility);
UAbilitySystemComponent::InternalTryActivateAbilityOriginal = decltype(UAbilitySystemComponent::InternalTryActivateAbilityOriginal)(InternalTryActivateAbility);
ABuildingActor::OnDamageServerOriginal = decltype(ABuildingActor::OnDamageServerOriginal)(OnDamageServer);
StaticLoadObjectOriginal = decltype(StaticLoadObjectOriginal)(StaticLoadObject);
// if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray);
// else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray);

View File

@@ -52,4 +52,14 @@ 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; }

View File

@@ -56,7 +56,12 @@ DWORD WINAPI Main(LPVOID)
static auto FortAbilitySystemComponentAthenaDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortAbilitySystemComponentAthena");
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" : L"Artemis_Terrain" : L"Apollo_Terrain";
FString Level = Engine_Version < 424
? L"Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501
? L"Asteria_Terrain"
: L"Artemis_Terrain"
: Globals::bCreative ? L"Creative_NoApollo_Terrain"
: L"Apollo_Terrain";
if (Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr))
{
@@ -109,8 +114,8 @@ DWORD WINAPI Main(LPVOID)
UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false);
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbilityWithEventData"),
UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook, nullptr, false);
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"),
UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false);
// Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"),
// UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false);
if (Engine_Version >= 424)
{

View File

@@ -72,6 +72,11 @@ static inline uint64 FindCreateNetDriver()
static inline uint64 FindKickPlayer()
{
if (Engine_Version >= 423 || Engine_Version <= 425)
return Memcury::Scanner::FindPattern("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC ? 49 8B F0 48 8B DA 48 85 D2").Get();
// return 0;
// return Memcury::Scanner::FindPattern("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC ? 49 8B F0 48 8B DA 48 85 D2").Get(); // 12.41
uint64 Ret = 0;
@@ -133,13 +138,29 @@ static inline uint64 FindSpawnActor()
static inline uint64 FindSetWorld()
{
return Memcury::Scanner::FindStringRef(L"AOnlineBeaconHost::InitHost failed")
.ScanFor({ 0x48, 0x8B, 0xD0, 0xE8 }, false)
.RelativeOffset(4)
.Get(); // THANKS ENDER
if (Engine_Version < 426)
return Memcury::Scanner::FindStringRef(L"AOnlineBeaconHost::InitHost failed")
.ScanFor({ 0x48, 0x8B, 0xD0, 0xE8 }, false)
.RelativeOffset(4)
.Get(); // THANKS ENDER
// return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8B EC 48 83 EC 30 48 8B 99").Get(); // s12 i think
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B 99 ? ? ? ? 48 8B F2 48 8B F9 48 85 DB 0F 84 ? ? ? ? 48 8B 97").Get();
int SetWorldIndex = 0;
int Fortnite_Season = std::floor(Fortnite_Version);
if (Fortnite_Season == 13)
SetWorldIndex = 0x70;
else if (Fortnite_Season == 14 || Fortnite_Version <= 15.2)
SetWorldIndex = 0x71;
else if (Fortnite_Version >= 15.3 && Fortnite_Season < 18) // i havent tested 15.2
SetWorldIndex = 0x72;
else if (Fortnite_Season == 18)
SetWorldIndex = 0x73;
else if (Fortnite_Season >= 19 && Fortnite_Season < 21)
SetWorldIndex = 0x7A;
static auto DefaultNetDriver = FindObject("/Script/Engine.Default__NetDriver");
return __int64(DefaultNetDriver->VFTable[SetWorldIndex]);
}
static inline uint64 FindInitListen()
@@ -154,6 +175,12 @@ static inline uint64 FindOnDamageServer()
return Addr;
}
static inline uint64 FindStaticLoadObject()
{
auto Addr = Memcury::Scanner::FindStringRef(L"STAT_LoadObject").ScanFor({ 0x4C, 0x89, 0x4C }, false);
return Addr.Get();
}
static inline uint64 FindNoMCP()
{
if (Fortnite_Version == 4)

View File

@@ -11,16 +11,37 @@
FAILED_STRINGREF = 1,
FAILED_CREATE_NETDRIVER = 2,
FAILED_LISTEN = 3
}; */
}; */
namespace Globals
{
extern inline bool bCreative = false;
}
extern inline UObject* (*StaticLoadObjectOriginal)(UClass*, UObject*, const wchar_t* InName, const wchar_t* Filename, uint32_t LoadFlags, UObject* Sandbox, bool bAllowObjectReconciliation) = nullptr;
template <typename T = UObject>
static inline T* FindObject(const TCHAR* Name, UClass* Class = nullptr)
static inline T* LoadObject(const TCHAR* Name, UClass* Class = nullptr, UObject* Outer = nullptr)
{
return StaticFindObject<T>(Class, nullptr, Name);
return (T*)StaticLoadObjectOriginal(Class, Outer, Name, nullptr, 0, nullptr, false);
}
template <typename T = UObject>
static inline T* FindObject(const std::string& NameStr, UClass* Class = nullptr)
static inline T* LoadObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr)
{
auto NameCWSTR = std::wstring(NameStr.begin(), NameStr.end()).c_str();
return (T*)StaticLoadObjectOriginal(Class, Outer, NameCWSTR, nullptr, 0, nullptr, false);
}
template <typename T = UObject>
static inline T* FindObject(const TCHAR* Name, UClass* Class = nullptr, UObject* Outer = nullptr)
{
auto res = (T*)StaticFindObject/*<T>*/(Class, Outer, Name);
return res;
}
template <typename T = UObject>
static inline T* FindObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr)
{
auto NameCWSTR = std::wstring(NameStr.begin(), NameStr.end()).c_str();
return StaticFindObject<T>(Class, nullptr, NameCWSTR);