fix 1.11 replication, fix some ltm specific stuff, start on shadow stones, fix some events not having foundations, fix s4-s6 gadgets, fix clear inventory on some versions
This commit is contained in:
Milxnor
2023-04-22 23:52:20 -04:00
parent 769dfa08ef
commit 5da8485485
57 changed files with 1869 additions and 888 deletions

View File

@@ -0,0 +1,44 @@
#pragma once
#include "BuildingGameplayActor.h"
#include "AthenaBarrierObjective.h"
struct FBarrierFlagDisplayData
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.BarrierFlagDisplayData");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UStaticMesh* GetHeadMesh()
{
static auto HeadMeshOffset = FindOffsetStruct("/Script/FortniteGame.BarrierFlagDisplayData", "HeadMesh");
return *(UStaticMesh**)(__int64(this) + HeadMeshOffset);
}
FVector& GetMeshScale()
{
static auto MeshScaleOffset = FindOffsetStruct("/Script/FortniteGame.BarrierFlagDisplayData", "MeshScale");
return *(FVector*)(__int64(this) + MeshScaleOffset);
}
};
class AAthenaBarrierFlag : public ABuildingGameplayActor
{
public:
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = GetOffset("FoodTeam");
return Get<EBarrierFoodTeam>(FoodTeamOffset);
}
FBarrierFlagDisplayData* GetDisplayData(EBarrierFoodTeam FoodTeam)
{
static auto FoodDisplayDataOffset = GetOffset("FoodDisplayData");
auto FoodDisplayData = Get<FBarrierFlagDisplayData*>(FoodDisplayDataOffset); // Array of size 2
return &FoodDisplayData[(int)FoodTeam];
}
};

View File

@@ -0,0 +1,59 @@
#pragma once
#include "BuildingGameplayActor.h"
using UStaticMesh = UObject;
using UMaterialInterface = UObject;
enum class EBarrierFoodTeam : uint8_t
{
Burger = 0,
Tomato = 1,
MAX = 2
};
struct FBarrierObjectiveDisplayData
{
UStaticMesh* HeadMesh; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector MeshScale; // 0x0008(0x000C) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector MeshRelativeOffset; // 0x0014(0x000C) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<UMaterialInterface*> MaterialsToSwap; // 0x0020(0x0010) (Edit, ZeroConstructor, NativeAccessSpecifierPublic)
};
class AAthenaBarrierObjective : public ABuildingGameplayActor
{
public:
void SetHeadMesh(UStaticMesh* NewMesh, const FVector& NewScale, const FVector& NewOffset, const TArray<UMaterialInterface*>& MaterialsToSwap)
{
static auto SetHeadMeshFn = FindObject<UFunction>("/Script/FortniteGame.AthenaBarrierObjective.SetHeadMesh");
struct
{
UStaticMesh* NewMesh; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector NewScale; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector NewOffset; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<UMaterialInterface*> MaterialsToSwap; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, NativeAccessSpecifierPublic)
} AAthenaBarrierObjective_SetHeadMesh_Params{ NewMesh, NewScale, NewOffset, MaterialsToSwap };
this->ProcessEvent(SetHeadMeshFn, &AAthenaBarrierObjective_SetHeadMesh_Params);
}
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = GetOffset("FoodTeam");
return Get<EBarrierFoodTeam>(FoodTeamOffset);
}
FBarrierObjectiveDisplayData* GetFoodDisplayData(EBarrierFoodTeam FoodTeam)
{
static auto FoodDisplayDataOffset = GetOffset("FoodDisplayData");
auto FoodDisplayData = Get<FBarrierObjectiveDisplayData*>(FoodDisplayDataOffset); // Array size of 2
return &FoodDisplayData[(int)FoodTeam];
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.AthenaBarrierObjective");
return Class;
}
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "BuildingGameplayActor.h"
class AAthenaBigBaseWall : public ABuildingGameplayActor
{
public:
};

View File

@@ -9,6 +9,9 @@ UObject* UClass::CreateDefaultObject()
auto name = this->GetFullName();
if (name.contains("Default__"))
return this;
auto defaultafqaf = defaultAbilities.find(name);
UObject* DefaultObject = nullptr;

View File

@@ -20,6 +20,7 @@ class UClass : public UStruct
{
public:
UObject* CreateDefaultObject();
UClass* GetSuperStruct() { return *(UClass**)(__int64(this) + Offsets::SuperStruct); } // idk if this is in UStruct
};
class UFunction : public UStruct

View File

@@ -1,2 +1,19 @@
#pragma once
#include "DelegateBase.h"
#include "DelegateSignatureImpl.inl"
#define FUNC_CONCAT( ... ) __VA_ARGS__
#define FUNC_DECLARE_DELEGATE( DelegateName, ReturnType, ... ) \
typedef TBaseDelegate/*<__VA_ARGS__>*/ DelegateName;
#define FUNC_DECLARE_DYNAMIC_DELEGATE( TWeakPtr, DynamicDelegateName, ExecFunction, FuncParamList, FuncParamPassThru, ... ) \
class DynamicDelegateName : public TBaseDynamicDelegate<TWeakPtr, __VA_ARGS__> \
{ \
public: \
DynamicDelegateName() \
{ \
} \
\
};

View File

@@ -2,19 +2,27 @@
#include "inc.h"
#include "TypeCompatibleBytes.h"
#include "ContainerAllocationPolicies.h"
/*
#if !defined(_WIN32) || defined(_WIN64)
// Let delegates store up to 32 bytes which are 16-byte aligned before we heap allocate
typedef TAlignedBytes<16, 16> FAlignedInlineDelegateType;
#if USE_SMALL_DELEGATES
typedef FHeapAllocator FDelegateAllocatorType;
#else
typedef TInlineAllocator<2> FDelegateAllocatorType;
#endif
*/
#else
// ... except on Win32, because we can't pass 16-byte aligned types by value, as some delegates are
// so we'll just keep it heap-allocated, which are always sufficiently aligned.
typedef TAlignedBytes<16, 8> FAlignedInlineDelegateType;
typedef FHeapAllocator FDelegateAllocatorType;
#endif
class FDelegateBase
{
public:
// FDelegateAllocatorType::ForElementType<FAlignedInlineDelegateType> DelegateAllocator;
// int32 DelegateSize;
FDelegateAllocatorType::ForElementType<FAlignedInlineDelegateType> DelegateAllocator;
int32 DelegateSize;
};

View File

@@ -0,0 +1,7 @@
#pragma once
#include "Delegate.h"
#include "ObjectMacros.h"
#define DECLARE_DELEGATE( DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, void )
#define DECLARE_DYNAMIC_DELEGATE( DelegateName ) /* BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) */ FUNC_DECLARE_DYNAMIC_DELEGATE( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, , FUNC_CONCAT( *this ), void )

View File

@@ -0,0 +1,16 @@
#pragma once
template <bool Const, typename Class, typename FuncType>
struct TMemFunPtrType;
template <typename Class, typename RetType, typename... ArgTypes>
struct TMemFunPtrType<false, Class, RetType(ArgTypes...)>
{
typedef RetType(Class::* Type)(ArgTypes...);
};
template <typename Class, typename RetType, typename... ArgTypes>
struct TMemFunPtrType<true, Class, RetType(ArgTypes...)>
{
typedef RetType(Class::* Type)(ArgTypes...) const;
};

View File

@@ -1,9 +1,63 @@
#pragma once
#include "DelegateBase.h"
#include "ScriptDelegates.h"
template <typename WrappedRetValType, typename... ParamTypes>
#include "DelegateInstanceInterface.h"
#include "RemoveReference.h"
#include "TypeWrapper.h"
// template <typename WrappedRetValType, typename... ParamTypes> // (Milxnor) IDK IM SCUFFED
class TBaseDelegate : public FDelegateBase
{
public:
// (Milxnor) YEAH NO
/*
typedef typename TUnwrapType<WrappedRetValType>::Type RetValType;
template <typename UserClass, typename... VarTypes>
FUNCTION_CHECK_RETURN_START
inline static TBaseDelegate<RetValType, ParamTypes...> CreateRaw(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
FUNCTION_CHECK_RETURN_END
{
// UE_STATIC_DEPRECATE(4.23, TIsConst<UserClass>::Value, "Binding a delegate with a const object pointer and non-const function is deprecated.");
TBaseDelegate<RetValType, ParamTypes...> Result;
TBaseRawMethodDelegateInstance<false, UserClass, TFuncType, VarTypes...>::Create(Result, InUserObject, InFunc, Vars...);
return Result;
}
template <typename UserClass, typename... VarTypes>
FUNCTION_CHECK_RETURN_START
inline static TBaseDelegate<RetValType, ParamTypes...> CreateRaw(UserClass* InUserObject, typename TMemFunPtrType<true, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
FUNCTION_CHECK_RETURN_END
{
TBaseDelegate<RetValType, ParamTypes...> Result;
TBaseRawMethodDelegateInstance<true, UserClass, TFuncType, VarTypes...>::Create(Result, InUserObject, InFunc, Vars...);
return Result;
}
template <typename UserClass, typename... VarTypes>
inline void BindRaw(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
{
// UE_STATIC_DEPRECATE(4.23, TIsConst<UserClass>::Value, "Binding a delegate with a const object pointer and non-const function is deprecated.");
*this = CreateRaw(const_cast<typename TRemoveConst<UserClass>::Type*>(InUserObject), InFunc, Vars...);
}
template <typename UserClass, typename... VarTypes>
inline void BindRaw(UserClass* InUserObject, typename TMemFunPtrType<true, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
{
*this = CreateRaw(InUserObject, InFunc, Vars...);
} */
};
template <typename TWeakPtr, typename RetValType, typename... ParamTypes>
class TBaseDynamicDelegate : public TScriptDelegate<TWeakPtr>
{
public:
/**
* Default constructor
*/
TBaseDynamicDelegate() { }
};

View File

@@ -2,6 +2,8 @@
#include "Object.h"
#include "DelegateCombinations.h"
enum class ESpawnActorCollisionHandlingMethod : uint8
{
Undefined,
@@ -16,3 +18,73 @@ struct FHitResult
static class UStruct* GetStruct();
static int GetStructSize();
};
struct FTimerHandle
{
FTimerHandle()
: Handle(0)
{
}
/** True if this handle was ever initialized by the timer manager */
bool IsValid() const
{
return Handle != 0;
}
/** Explicitly clear handle */
void Invalidate()
{
Handle = 0;
}
bool operator==(const FTimerHandle& Other) const
{
return Handle == Other.Handle;
}
bool operator!=(const FTimerHandle& Other) const
{
return Handle != Other.Handle;
}
/* FString ToString() const
{
return FString::Printf(TEXT("%llu"), Handle);
} */
// private:
static const uint32 IndexBits = 24;
static const uint32 SerialNumberBits = 40;
static_assert(IndexBits + SerialNumberBits == 64, "The space for the timer index and serial number should total 64 bits");
static const int32 MaxIndex = (int32)1 << IndexBits;
static const uint64 MaxSerialNumber = (uint64)1 << SerialNumberBits;
void SetIndexAndSerialNumber(int32 Index, uint64 SerialNumber)
{
// check(Index >= 0 && Index < MaxIndex);
// check(SerialNumber < MaxSerialNumber);
Handle = (SerialNumber << IndexBits) | (uint64)(uint32)Index;
}
FORCEINLINE int32 GetIndex() const
{
return (int32)(Handle & (uint64)(MaxIndex - 1));
}
FORCEINLINE uint64 GetSerialNumber() const
{
return Handle >> IndexBits;
}
uint64 Handle;
/* friend uint32 GetTypeHash(const FTimerHandle& InHandle)
{
return GetTypeHash(InHandle.Handle);
} */
};
DECLARE_DYNAMIC_DELEGATE(FTimerDynamicDelegate);

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -1,8 +1,33 @@
#pragma once
#include <functional>
#include "Actor.h"
#include "Stack.h"
#include "ScriptInterface.h"
#include "FortGameStateAthena.h"
#include "GameplayStatics.h"
class AFortAthenaMutator : public AActor // AFortGameplayMutator
{
public:
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
return Class;
}
};
static inline void LoopMutators(std::function<void(AFortAthenaMutator*)> Callback)
{
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortAthenaMutator::StaticClass());
for (int i = 0; i < AllMutators.Num(); i++)
{
Callback((AFortAthenaMutator*)AllMutators.at(i));
}
AllMutators.Free();
}

View File

@@ -0,0 +1,30 @@
#include "FortAthenaMutator_Barrier.h"
void AFortAthenaMutator_Barrier::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
/*
TScriptInterface<UObject> SafeZoneInterface;
EAthenaGamePhaseStep GamePhaseStep;
static auto SafeZoneInterfaceOffset = FindOffsetStruct("/Script/FortniteGame.FortAthenaMutator_Barrier.OnGamePhaseStepChanged", "SafeZoneInterface", false);
if (SafeZoneInterfaceOffset != -1)
Stack.StepCompiledIn(&SafeZoneInterface);
Stack.StepCompiledIn(&GamePhaseStep);
LOG_INFO(LogDev, "{} GamePhaseStep: {}", __FUNCTION__, (int)GamePhaseStep);
if (GamePhaseStep == EAthenaGamePhaseStep::Warmup)
{
// idk when they spawn the barrier could also be warmup or something
}
else if (GamePhaseStep == EAthenaGamePhaseStep::BusLocked)
{
// idk if they spawn the heads on flying or locked
}
*/
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,73 @@
#pragma once
#include "FortAthenaMutator.h"
#include "AthenaBigBaseWall.h"
#include "AthenaBarrierObjective.h"
#include "AthenaBarrierFlag.h"
struct FBarrierTeamState // Idk if this actually changes
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.BarrierTeamState");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = FindOffsetStruct("/Script/FortniteGame.BarrierTeamState", "FoodTeam");
return *(EBarrierFoodTeam*)(__int64(this) + FoodTeamOffset);
}
AAthenaBarrierFlag*& GetObjectiveFlag()
{
static auto ObjectiveFlagOffset = FindOffsetStruct("/Script/FortniteGame.BarrierTeamState", "ObjectiveFlag");
return *(AAthenaBarrierFlag**)(__int64(this) + ObjectiveFlagOffset);
}
AAthenaBarrierObjective*& GetObjectiveObject()
{
static auto ObjectiveObjectOffset = FindOffsetStruct("/Script/FortniteGame.BarrierTeamState", "ObjectiveObject");
return *(AAthenaBarrierObjective**)(__int64(this) + ObjectiveObjectOffset);
}
};
class AFortAthenaMutator_Barrier : public AFortAthenaMutator
{
public:
static inline void (*OnGamePhaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret);
UClass* GetBigBaseWallClass()
{
static auto BigBaseWallClassOffset = GetOffset("BigBaseWallClass");
return Get<UClass*>(BigBaseWallClassOffset);
}
UClass* GetObjectiveFlagClass()
{
static auto ObjectiveFlagOffset = GetOffset("ObjectiveFlag");
return Get<UClass*>(ObjectiveFlagOffset);
}
AAthenaBigBaseWall*& GetBigBaseWall()
{
static auto BigBaseWallOffset = GetOffset("BigBaseWall");
return Get<AAthenaBigBaseWall*>(BigBaseWallOffset);
}
FBarrierTeamState* GetTeam_0_State()
{
static auto Team_0_StateOffset = GetOffset("Team_0_State");
return GetPtr<FBarrierTeamState>(Team_0_StateOffset);
}
FBarrierTeamState* GetTeam_1_State()
{
static auto Team_1_StateOffset = GetOffset("Team_1_State");
return GetPtr<FBarrierTeamState>(Team_1_StateOffset);
}
static void OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -0,0 +1,18 @@
#include "FortAthenaMutator_Disco.h"
void AFortAthenaMutator_Disco::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
TScriptInterface<UObject> SafeZoneInterface;
EAthenaGamePhaseStep GamePhaseStep = EAthenaGamePhaseStep::BusFlying;
static auto SafeZoneInterfaceOffset = FindOffsetStruct("/Script/FortniteGame.FortAthenaMutator_Disco.OnGamePhaseStepChanged", "SafeZoneInterface", false);
if (SafeZoneInterfaceOffset != -1)
Stack.StepCompiledIn(&SafeZoneInterface);
// Stack.StepCompiledIn(&GamePhaseStep, true);
LOG_INFO(LogDev, "{} GamePhaseStep: {}", __FUNCTION__, (int)GamePhaseStep);
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "FortAthenaMutator.h"
#include "Array.h"
struct FControlPointSpawnData
{
};
class AFortAthenaMutator_Disco : public AFortAthenaMutator
{
public:
static inline void (*OnGamePhaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret);
TArray<FControlPointSpawnData>& GetControlPointSpawnData()
{
static auto ControlPointSpawnDataOffset = GetOffset("ControlPointSpawnData");
return Get<TArray<FControlPointSpawnData>>(ControlPointSpawnDataOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_Disco");
return Class;
}
static void OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -10,19 +10,41 @@
struct FGunGameGunEntry
{
UFortWeaponItemDefinition* Weapon; // 0x0000(0x0008) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FScalableFloat Enabled; // 0x0008(0x0020) (Edit, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat AwardAtElim; // 0x0028(0x0020) (Edit, DisableEditOnInstance, NativeAccessSpecifierPublic)
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.GunGameGunEntry");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UFortWeaponItemDefinition*& GetWeapon()
{
static auto WeaponOffset = FindOffsetStruct("/Script/FortniteGame.GunGameGunEntry", "Weapon");
return *(UFortWeaponItemDefinition**)(__int64(this) + WeaponOffset);
}
FScalableFloat& GetEnabled()
{
static auto EnabledOffset = FindOffsetStruct("/Script/FortniteGame.GunGameGunEntry", "Enabled");
return *(FScalableFloat*)(__int64(this) + EnabledOffset);
}
FScalableFloat& GetAwardAtElim()
{
static auto AwardAtElimOffset = FindOffsetStruct("/Script/FortniteGame.GunGameGunEntry", "AwardAtElim");
return *(FScalableFloat*)(__int64(this) + AwardAtElimOffset);
}
};
struct FGunGameGunEntries
{
TArray<struct FGunGameGunEntry> Entries; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic)
TArray<FGunGameGunEntry> Entries; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic)
};
struct FGunGamePlayerData
{
TArray<class UFortWeaponItemDefinition*> CurrentlyAssignedWeapons; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic)
TArray<UFortWeaponItemDefinition*> CurrentlyAssignedWeapons; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_GG : public AFortAthenaMutator
@@ -50,7 +72,7 @@ public:
{
auto& AwardEntriesAtElimMap = GetAwardEntriesAtElimMap();
float Value = 0;
float Value = 0; // TODO Get from AwardAtElim
for (auto& AwardEntry : AwardEntriesAtElimMap)
{

View File

@@ -2,7 +2,7 @@
void AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
LOG_INFO(LogDev, "OnGamePhaseStepChangedHook!");
LOG_INFO(LogDev, __FUNCTION__);
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
}

View File

@@ -9,8 +9,25 @@
struct FItemsToGive
{
UFortWorldItemDefinition* ItemToDrop; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FScalableFloat NumberToGive; // 0x0008(0x0020) (Edit, NativeAccessSpecifierPublic)
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.ItemsToGive");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UFortWorldItemDefinition*& GetItemToDrop()
{
static auto ItemToDropOffset = FindOffsetStruct("/Script/FortniteGame.ItemsToGive", "ItemToDrop");
return *(UFortWorldItemDefinition**)(__int64(this) + ItemToDropOffset);
}
FScalableFloat& GetNumberToGive()
{
static auto NumberToGiveOffset = FindOffsetStruct("/Script/FortniteGame.ItemsToGive", "NumberToGive");
return *(FScalableFloat*)(__int64(this) + NumberToGiveOffset);
}
};
class AFortAthenaMutator_GiveItemsAtGamePhaseStep : public AFortAthenaMutator

View File

@@ -0,0 +1,36 @@
#pragma once
#include "FortAthenaMutator.h"
#include "GameplayAbilityTypes.h"
#include "reboot.h"
struct FFortPieSliceSpawnData
{
FScalableFloat SpawnDirection; // 0x0000(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat SpawnDirectionDeviation; // 0x0020(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat MinSpawnDistanceFromCenter; // 0x0040(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat MaxSpawnDistanceFromCenter; // 0x0060(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
};
struct FHeistExitCraftSpawnData : public FFortPieSliceSpawnData
{
FScalableFloat SpawnDelayTime; // 0x0080(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat SafeZonePhaseWhenToSpawn; // 0x00A0(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat SafeZonePhaseWhereToSpawn; // 0x00C0(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_Heist : public AFortAthenaMutator
{
public:
TArray<FHeistExitCraftSpawnData>& GetHeistExitCraftSpawnData()
{
static auto HeistExitCraftSpawnDataOffset = GetOffset("HeistExitCraftSpawnData");
return Get<TArray<FHeistExitCraftSpawnData>>(HeistExitCraftSpawnDataOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_Heist");
return Class;
}
};

View File

@@ -2,7 +2,123 @@
#include "FortAthenaMutator.h"
enum class EAthenaLootDropOverride : uint8_t
{
NoOverride = 0,
ForceDrop = 1,
ForceKeep = 2,
ForceDestroy = 3,
ForceDropUnlessRespawning = 4,
ForceDestroyUnlessRespawning = 5,
EAthenaLootDropOverride_MAX = 6
};
enum class EAthenaInventorySpawnOverride : uint8_t
{
NoOverride = 0,
Always = 1,
IntialSpawn = 2,
AircraftPhaseOnly = 3,
EAthenaInventorySpawnOverride_MAX = 4
};
struct FItemLoadoutContainer
{
TArray<FItemAndCount> Loadout;
};
struct FItemLoadoutTeamMap
{
unsigned char TeamIndex; // 0x0000(0x0001) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
unsigned char LoadoutIndex; // 0x0001(0x0001) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EAthenaInventorySpawnOverride UpdateOverrideType; // 0x0002(0x0001) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EAthenaLootDropOverride DropAllItemsOverride; // 0x0003(0x0001) (Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_InventoryOverride : public AFortAthenaMutator
{
public:
TArray<FItemLoadoutContainer>& GetInventoryLoadouts()
{
static auto InventoryLoadoutsOffset = GetOffset("InventoryLoadouts");
return Get<TArray<FItemLoadoutContainer>>(InventoryLoadoutsOffset);
}
TArray<FItemLoadoutTeamMap>& GetTeamLoadouts()
{
static auto TeamLoadoutsOffset = GetOffset("TeamLoadouts");
return Get<TArray<FItemLoadoutTeamMap>>(TeamLoadoutsOffset);
}
FItemLoadoutTeamMap GetLoadoutTeamForTeamIndex(uint8_t TeamIndex)
{
auto& TeamLoadouts = GetTeamLoadouts();
for (int i = 0; i < TeamLoadouts.Num(); i++)
{
auto& TeamLoadout = TeamLoadouts.at(i);
if (TeamLoadout.TeamIndex == TeamIndex)
return TeamLoadout;
}
return FItemLoadoutTeamMap();
}
FItemLoadoutContainer GetLoadoutContainerForTeamIndex(uint8_t TeamIndex)
{
auto LoadoutTeam = GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.TeamIndex == TeamIndex)
{
auto& InventoryLoadouts = GetInventoryLoadouts();
if (InventoryLoadouts.Num() - 1 < LoadoutTeam.LoadoutIndex)
return FItemLoadoutContainer();
return InventoryLoadouts.at(LoadoutTeam.LoadoutIndex);
}
return FItemLoadoutContainer();
}
EAthenaInventorySpawnOverride& GetInventoryUpdateOverride(uint8_t TeamIndex = 255)
{
if (TeamIndex != 255)
{
auto LoadoutTeam = GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.TeamIndex == TeamIndex)
{
if (LoadoutTeam.UpdateOverrideType != EAthenaInventorySpawnOverride::NoOverride)
return LoadoutTeam.UpdateOverrideType;
}
}
static auto InventoryUpdateOverrideOffset = GetOffset("InventoryUpdateOverride");
return Get<EAthenaInventorySpawnOverride>(InventoryUpdateOverrideOffset);
}
EAthenaLootDropOverride& GetDropAllItemsOverride(uint8_t TeamIndex = 255)
{
if (TeamIndex != 255)
{
auto LoadoutTeam = GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.TeamIndex == TeamIndex)
{
if (LoadoutTeam.DropAllItemsOverride != EAthenaLootDropOverride::NoOverride)
return LoadoutTeam.DropAllItemsOverride;
}
}
static auto DropAllItemsOverrideOffset = GetOffset("DropAllItemsOverride");
return Get<EAthenaLootDropOverride>(DropAllItemsOverrideOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_InventoryOverride");
return Class;
}
};

View File

@@ -24,6 +24,7 @@
#include "OnlineReplStructs.h"
#include "BGA.h"
#include "vendingmachine.h"
#include "FortAthenaMutator.h"
static UFortPlaylist* GetPlaylistToUse()
{
@@ -212,7 +213,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
auto Fortnite_Season = std::floor(Fortnite_Version);
if (false) // Manual foundation showing
// if (false) // Manual foundation showing
{
if (Fortnite_Season >= 7 && Fortnite_Season <= 10)
{
@@ -548,6 +549,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
Globals::bStartedListening = true;
}
bool Ret = false;
if (Engine_Version >= 424) // returning true is stripped on c2+
{
static auto WarmupRequiredPlayerCountOffset = GameMode->GetOffset("WarmupRequiredPlayerCount");
@@ -561,13 +564,67 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
// if (MapInfo->Get<TArray<__int64>>(FlightInfosOffset).ArrayNum > 0)
{
LOG_INFO(LogDev, "ReadyToStartMatch Return Address: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0)));
return true;
Ret = true;
}
}
}
}
return Athena_ReadyToStartMatchOriginal(GameMode);
if (!Ret)
Ret = Athena_ReadyToStartMatchOriginal(GameMode);
if (Ret)
{
// We are assuming it successfully became warmup.
static auto mutatorClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass);
std::vector<std::pair<AFortAthenaMutator*, UFunction*>> FunctionsToCall;
for (int i = 0; i < AllMutators.Num(); i++)
{
auto Mutator = (AFortAthenaMutator*)AllMutators.at(i);
FunctionsToCall.push_back(std::make_pair(Mutator, Mutator->FindFunction("OnGamePhaseStepChanged")));
}
static int LastNum1 = 3125;
if (LastNum1 != Globals::AmountOfListens)
{
LastNum1 = Globals::AmountOfListens;
for (auto& FunctionToCallPair : FunctionsToCall)
{
// On newer versions there is a second param.
LOG_INFO(LogDev, "FunctionToCallPair.second: {}", __int64(FunctionToCallPair.second));
if (FunctionToCallPair.second)
{
if (Fortnite_Version < 10)
{
// mem leak btw
auto a = ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::None);
if (a)
{
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, a);
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::Setup));
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::Warmup));
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormFormingGamePhaseStep);
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormHoldingGamePhaseStep);
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormShrinkingGamePhaseStep);
}
}
}
}
}
}
return Ret;
}
int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller)
@@ -580,11 +637,26 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
UObject* Playlist = nullptr;
UFortPlaylist* Playlist = nullptr;
bool bVersionHasPlaylist = false;
if (CurrentPlaylistDataOffset != -1 || Fortnite_Version >= 6)
{
bVersionHasPlaylist = true;
Playlist = CurrentPlaylistDataOffset == -1 && Fortnite_Version < 6 ? nullptr : GameState->GetCurrentPlaylist();
}
static int DefaultFirstTeam = 3;
if (Playlist)
{
static auto bIsLargeTeamGameOffset = Playlist->GetOffset("bIsLargeTeamGame");
bool bIsLargeTeamGame = Playlist->Get<bool>(bIsLargeTeamGameOffset);
}
static int CurrentTeamMembers = 0; // bad
static int Current = 3;
static int Current = DefaultFirstTeam;
static int LastNum = 1;
@@ -592,7 +664,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
{
LastNum = AmountOfRestarts;
Current = 3;
Current = DefaultFirstTeam;
CurrentTeamMembers = 0;
}
@@ -603,10 +675,8 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
bool bShouldSpreadTeams = false;
if (CurrentPlaylistDataOffset != -1 || Fortnite_Version >= 6)
if (bVersionHasPlaylist)
{
Playlist = CurrentPlaylistDataOffset == -1 && Fortnite_Version < 6 ? nullptr : GameState->GetCurrentPlaylist();
if (!Playlist)
{
CurrentTeamMembers = 0;
@@ -754,7 +824,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
// CurrentActor->K2_DestroyActor();
// continue;
if (Engine_Version != 419)
// if (Engine_Version != 419)
{
auto Location = CurrentActor->GetActorLocation();
Location.Z += UpZ;

View File

@@ -9,6 +9,33 @@
} */
TScriptInterface<UFortSafeZoneInterface> AFortGameStateAthena::GetSafeZoneInterface()
{
int Offset = -1;
if (Fortnite_Version == 10.40)
{
// Offset = 0xF60;
}
TScriptInterface<UFortSafeZoneInterface> ScriptInterface{};
if (Offset != -1)
{
auto idk = (void*)(__int64(this) + Offset);
UObject* ObjectPtr = reinterpret_cast<UObject* (*)(__int64)>(((UObject*)idk)->VFTable[0x1])(__int64(idk)); // not actually a uobject but its just how we can get vft
if (ObjectPtr)
{
ScriptInterface.ObjectPointer = ObjectPtr;
ScriptInterface.InterfacePointer = ObjectPtr->GetInterfaceAddress(UFortSafeZoneInterface::StaticClass());
}
}
return ScriptInterface;
}
UFortPlaylist*& AFortGameStateAthena::GetCurrentPlaylist()
{
static auto CurrentPlaylistInfoOffset = GetOffset("CurrentPlaylistInfo", false);

View File

@@ -4,6 +4,26 @@
#include "FortPlayerState.h"
#include "FortPlaylist.h"
#include "BuildingStructuralSupportSystem.h"
#include "ScriptInterface.h"
#include "Interface.h"
enum class EAthenaGamePhaseStep : uint8_t // idk if this changes
{
None = 0,
Setup = 1,
Warmup = 2,
GetReady = 3,
BusLocked = 4,
BusFlying = 5,
StormForming = 6,
StormHolding = 7,
StormShrinking = 8,
Countdown = 9,
FinalCountdown = 10,
EndGame = 11,
Count = 12,
EAthenaGamePhaseStep_MAX = 13
};
enum class EAthenaGamePhase : uint8_t
{
@@ -17,6 +37,16 @@ enum class EAthenaGamePhase : uint8_t
EAthenaGamePhase_MAX = 7
};
class UFortSafeZoneInterface : public UInterface
{
public:
static UClass* StaticClass()
{
static auto Struct = FindObject<UClass>("/Script/FortniteGame.FortSafeZoneInterface");
return Struct;
}
};
struct FPlayerBuildableClassContainer
{
TArray<UClass*> BuildingClasses; // 0x0000(0x0010) (ZeroConstructor, Transient, UObjectWrapper, NativeAccessSpecifierPublic)
@@ -50,6 +80,7 @@ public:
}
UFortPlaylist*& GetCurrentPlaylist();
TScriptInterface<UFortSafeZoneInterface> GetSafeZoneInterface();
// void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState);
@@ -59,3 +90,35 @@ public:
void OnRep_GamePhase();
void OnRep_CurrentPlaylistInfo();
};
static void* ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep GamePhaseStep)
{
struct AFortAthenaAIBotController_OnGamePhaseStepChanged_Params
{
TScriptInterface<UFortSafeZoneInterface> SafeZoneInterface; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, IsPlainOldData, NoDestructor, UObjectWrapper, NativeAccessSpecifierPublic)
EAthenaGamePhaseStep GamePhaseStep; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
bool bHasSafeZoneInterfaceParam = Fortnite_Version >= 10; // idk what version
AFortAthenaAIBotController_OnGamePhaseStepChanged_Params* Params = Alloc<AFortAthenaAIBotController_OnGamePhaseStepChanged_Params>();
if (bHasSafeZoneInterfaceParam)
{
auto GameState = (AFortGameStateAthena*)GetWorld()->GetGameState();
auto Interface = GameState->GetSafeZoneInterface();
if (!Interface.ObjectPointer)
return nullptr;
Params->SafeZoneInterface = Interface;
Params->GamePhaseStep = GamePhaseStep;
}
else
{
*(EAthenaGamePhaseStep*)(__int64(Params) + 0) = GamePhaseStep;
}
return Params;
}

View File

@@ -3,10 +3,54 @@
#include "Object.h"
#include "Stack.h"
#include "GameplayAbilityTypes.h"
#include "FortWorldItemDefinition.h"
struct FActiveItemGrantInfo
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.ActiveItemGrantInfo");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UFortWorldItemDefinition*& GetItem()
{
static auto ItemOffset = FindOffsetStruct("/Script/FortniteGame.ActiveItemGrantInfo", "Item");
return *(UFortWorldItemDefinition**)(__int64(this) + ItemOffset);
}
FScalableFloat& GetAmountToGive()
{
static auto AmountToGiveOffset = FindOffsetStruct("/Script/FortniteGame.ActiveItemGrantInfo", "AmountToGive");
return *(FScalableFloat*)(__int64(this) + AmountToGiveOffset);
}
FScalableFloat& GetMaxAmount()
{
static auto MaxAmountOffset = FindOffsetStruct("/Script/FortniteGame.ActiveItemGrantInfo", "MaxAmount");
return *(FScalableFloat*)(__int64(this) + MaxAmountOffset);
}
};
class UFortGameplayAbilityAthena_PeriodicItemGrant : public UObject // UFortGameplayAbility
{
public:
static inline void (*StartItemAwardTimersOriginal)(UObject* Context, FFrame& Stack, void* Ret);
TMap<FActiveItemGrantInfo, FScalableFloat>& GetItemsToGrant()
{
static auto ItemsToGrantOffset = GetOffset("ItemsToGrant");
return Get<TMap<FActiveItemGrantInfo, FScalableFloat>>(ItemsToGrantOffset);
}
TArray<FTimerHandle>& GetActiveTimers()
{
static auto ActiveTimersOffset = GetOffset("ActiveTimers");
return Get<TArray<FTimerHandle>>(ActiveTimersOffset);
}
static void StartItemAwardTimersHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -160,13 +160,8 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
auto ReplicatedEntryIdx = GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FortItemEntrySize);
// GetItemList().GetReplicatedEntries().AtPtr(ReplicatedEntryIdx, FFortItemEntry::GetStructSize())->GetIsReplicatedCopy() = true;
if (WorldItemDefinition->IsValidLowLevel())
if (FortPlayerController && WorldItemDefinition->IsValidLowLevel())
{
if (WorldItemDefinition->ShouldFocusWhenAdded()) // Should we also do this for stacking?
{
FortPlayerController->ServerExecuteInventoryItemHook(FortPlayerController, NewItemInstance->GetItemEntry()->GetItemGuid());
}
bool AreGadgetsEnabled = Addresses::ApplyGadgetData && Addresses::RemoveGadgetData && Globals::bEnableAGIDs;
if (AreGadgetsEnabled)
@@ -180,10 +175,25 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
bool (*ApplyGadgetData)(UFortGadgetItemDefinition * a1, __int64 a2, UFortItem* a3, unsigned __int8 a4) = decltype(ApplyGadgetData)(Addresses::ApplyGadgetData);
static auto FortInventoryOwnerInterfaceClass = FindObject<UClass>("/Script/FortniteGame.FortInventoryOwnerInterface");
auto Interface = __int64(PlayerController->GetInterfaceAddress(FortInventoryOwnerInterfaceClass));
auto Interface = __int64(FortPlayerController->GetInterfaceAddress(FortInventoryOwnerInterfaceClass));
LOG_INFO(LogDev, "Res: {}", ApplyGadgetData(GadgetItemDefinition, Interface, NewItemInstance, true));
if (Fortnite_Version < 7)
{
auto PickaxeInstance = GetPickaxeInstance();
if (PickaxeInstance)
{
RemoveItem(PickaxeInstance->GetItemEntry()->GetItemGuid(), nullptr, PickaxeInstance->GetItemEntry()->GetCount(), true);
}
}
}
}
if (WorldItemDefinition->ShouldFocusWhenAdded()) // Should we also do this for stacking?
{
FortPlayerController->ServerExecuteInventoryItemHook(FortPlayerController, NewItemInstance->GetItemEntry()->GetItemGuid());
}
}
else
{
@@ -343,6 +353,21 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
{
LOG_INFO(LogDev, "Unequipping Gadget!");
GadgetItemDefinition->UnequipGadgetData(FortPlayerController, ItemInstances.at(i));
if (Fortnite_Version < 7)
{
auto CosmeticLoadout = FortPlayerController->GetCosmeticLoadout();
// LOG_INFO(LogDev, "CosmeticLoadout: {}", __int64(CosmeticLoadout));
auto CosmeticLoadoutPickaxe = CosmeticLoadout ? CosmeticLoadout->GetPickaxe() : nullptr;
// LOG_INFO(LogDev, "CosmeticLoadoutPickaxe: {}", __int64(CosmeticLoadoutPickaxe));
// LOG_INFO(LogDev, "CosmeticLoadoutPickaxe Name: {}", CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->GetFullName() : "InvalidObject");
static auto WeaponDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.AthenaPickaxeItemDefinition", "WeaponDefinition");
auto PickaxeDefinition = CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get<UFortItemDefinition*>(WeaponDefinitionOffset)
: FindObject<UFortItemDefinition>(L"/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_Athena_C_T01.WID_Harvest_Pickaxe_Athena_C_T01");
this->AddItem(PickaxeDefinition, nullptr);
}
}
}

View File

@@ -890,7 +890,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
if (!ItemDefinition || !ItemDefinition->CanBeDropped())
return;
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop())
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop)
{
auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(),
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn);

View File

@@ -9,6 +9,72 @@
#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h"
#include "DataTableFunctionLibrary.h"
void AFortPlayerControllerAthena::StartGhostModeHook(UObject* Context, FFrame* Stack, void* Ret)
{
LOG_INFO(LogDev, __FUNCTION__);
auto Controller = (AFortPlayerControllerAthena*)Context;
UFortWorldItemDefinition* ItemProvidingGhostMode = nullptr;
Stack->StepCompiledIn(&ItemProvidingGhostMode);
if (!ItemProvidingGhostMode)
return StartGhostModeOriginal(Context, Stack, Ret);
// if (!Controller->HasAuthority) return StartGhostModeOriginal(Context, Stack, Ret);
// if (Controller->GhostModeRepData.bInGhostMode) return StartGhostModeOriginal(Context, Stack, Ret);
auto WorldInventory = Controller->GetWorldInventory();
if (!WorldInventory)
return StartGhostModeOriginal(Context, Stack, Ret);
bool bShouldUpdate = false;
auto NewAndModifiedInstances = WorldInventory->AddItem(ItemProvidingGhostMode, &bShouldUpdate, 1);
auto GhostModeItemInstance = NewAndModifiedInstances.first[0];
if (!GhostModeItemInstance)
return StartGhostModeOriginal(Context, Stack, Ret);
if (bShouldUpdate)
WorldInventory->Update();
Controller->ServerExecuteInventoryItemHook(Controller, GhostModeItemInstance->GetItemEntry()->GetItemGuid());
return StartGhostModeOriginal(Context, Stack, Ret);
}
void AFortPlayerControllerAthena::EndGhostModeHook(AFortPlayerControllerAthena* PlayerController)
{
// I believe there are a lot of other places we should remove it (go to XREFs of K2_RemoveItemFromPlayer on a version like 6.21, and there will be something checking ghost stuff).
LOG_INFO(LogDev, __FUNCTION__);
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return EndGhostModeOriginal(PlayerController);
auto GhostModeRepData = PlayerController->GetGhostModeRepData();
auto GhostModeItemDef = GhostModeRepData->GetGhostModeItemDef();
auto GhostModeItemInstance = WorldInventory->FindItemInstance(GhostModeItemDef);
if (GhostModeItemInstance)
{
bool bShouldUpdate = false;
int Count = 1; // GhostModeItemInstance->GetItemEntry()->GetCount()
WorldInventory->RemoveItem(GhostModeItemInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, Count);
if (bShouldUpdate)
WorldInventory->Update();
}
return EndGhostModeOriginal(PlayerController);
}
void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraft)
{
auto PlayerController = Cast<AFortPlayerController>(Engine_Version < 424 ? PC : ((UActorComponent*)PC)->GetOwner());
@@ -16,7 +82,7 @@ void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraf
if (!PlayerController)
return;
LOG_INFO(LogDev, "EnterAircraftHook");
// LOG_INFO(LogDev, "EnterAircraftHook");
EnterAircraftOriginal(PC, Aircraft);
@@ -55,36 +121,49 @@ void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraf
static auto mutatorClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass);
std::vector<std::pair<AFortAthenaMutator*, UFunction*>> FunctionsToCall;
for (int i = 0; i < AllMutators.Num(); i++)
{
auto Mutator = AllMutators.at(i);
auto Mutator = (AFortAthenaMutator*)AllMutators.at(i);
LOG_INFO(LogDev, "[{}] Mutator: {}", i, Mutator->GetFullName());
FunctionsToCall.push_back(std::make_pair(Mutator, Mutator->FindFunction("OnGamePhaseStepChanged")));
if (auto GiveItemsAtGamePhaseStepMutator = Cast<AFortAthenaMutator_GiveItemsAtGamePhaseStep>(Mutator))
{
auto PhaseToGive = GiveItemsAtGamePhaseStepMutator->GetPhaseToGiveItems();
LOG_INFO(LogDev, "[{}] PhaseToGiveItems: {}", i, (int)PhaseToGive);
auto& ItemsToGive = GiveItemsAtGamePhaseStepMutator->GetItemsToGive();
LOG_INFO(LogDev, "[{}] ItemsToGive.Num(): {}", i, ItemsToGive.Num());
LOG_INFO(LogDev, "[{}] PhaseToGiveItems: {} ItemsToGive.Num(): {}", i, (int)PhaseToGive, ItemsToGive.Num());
if (PhaseToGive <= 5) // Flying or lower
{
for (int j = 0; j < ItemsToGive.Num(); j++)
{
auto& ItemToGive = ItemsToGive.at(j);
auto ItemToGive = ItemsToGive.AtPtr(j, FItemsToGive::GetStructSize());
if (!ItemToGive->GetItemToDrop())
continue;
float Out = 1;
FString ContextString;
EEvaluateCurveTableResult result;
// UDataTableFunctionLibrary::EvaluateCurveTableRow(ItemToGive.NumberToGive.GetCurve().CurveTable, ItemToGive.NumberToGive.GetCurve().RowName, 0.f, ContextString, &result, &Out);
float Out2 = 0;
LOG_INFO(LogDev, "Out: {}", Out);
if (!IsBadReadPtr(ItemToGive->GetNumberToGive().GetCurve().CurveTable, 8) && ItemToGive->GetNumberToGive().GetCurve().RowName.IsValid())
{
UDataTableFunctionLibrary::EvaluateCurveTableRow(ItemToGive->GetNumberToGive().GetCurve().CurveTable, ItemToGive->GetNumberToGive().GetCurve().RowName,
0.f, ContextString, &result, &Out2);
}
WorldInventory->AddItem(ItemToGive.ItemToDrop, nullptr, Out);
LOG_INFO(LogDev, "[{}] [{}] Out: {} Out2: {} ItemToGive.ItemToDrop: {}", i, j, Out, Out2, ItemToGive->GetItemToDrop()->IsValidLowLevel() ? ItemToGive->GetItemToDrop()->GetFullName() : "BadRead");
if (!Out2)
continue;
WorldInventory->AddItem(ItemToGive->GetItemToDrop(), nullptr, Out2);
}
}
}
@@ -101,7 +180,43 @@ void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraf
} */
}
static int LastNum1 = 3125;
if (LastNum1 != Globals::AmountOfListens)
{
LastNum1 = Globals::AmountOfListens;
for (auto& FunctionToCallPair : FunctionsToCall)
{
// On newer versions there is a second param.
LOG_INFO(LogDev, "FunctionToCallPair.second: {}", __int64(FunctionToCallPair.second));
if (FunctionToCallPair.second)
{
{
// mem leak btw
auto a = ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::GetReady);
if (a)
{
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, a);
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::BusLocked));
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::BusFlying));
}
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormFormingGamePhaseStep);
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormHoldingGamePhaseStep);
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormShrinkingGamePhaseStep);
}
}
}
}
WorldInventory->Update();
// Should we equip the pickaxe for older builds here?
}
void AFortPlayerControllerAthena::ServerRequestSeatChangeHook(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex)

View File

@@ -73,6 +73,21 @@ static void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID, bool bUseServerChooseP
// PlayerState->Get(HeroTypeOffset) = HeroDefinition;
}
struct FGhostModeRepData
{
bool& IsInGhostMode()
{
static auto bInGhostModeOffset = FindOffsetStruct("/Script/FortniteGame.GhostModeRepData", "bInGhostMode");
return *(bool*)(__int64(this) + bInGhostModeOffset);
}
UFortWorldItemDefinition*& GetGhostModeItemDef()
{
static auto GhostModeItemDefOffset = FindOffsetStruct("/Script/FortniteGame.GhostModeRepData", "GhostModeItemDef");
return *(UFortWorldItemDefinition**)(__int64(this) + GhostModeItemDefOffset);
}
};
class AFortPlayerControllerAthena : public AFortPlayerController
{
public:
@@ -80,18 +95,28 @@ public:
static inline void (*ServerReadyToStartMatchOriginal)(AFortPlayerControllerAthena* PlayerController);
static inline void (*ServerRequestSeatChangeOriginal)(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex);
static inline void (*EnterAircraftOriginal)(UObject* PC, AActor* Aircraft);
static inline void (*StartGhostModeOriginal)(UObject* Context, FFrame* Stack, void* Ret);
static inline void (*EndGhostModeOriginal)(AFortPlayerControllerAthena* PlayerController);
AFortPlayerStateAthena* GetPlayerStateAthena()
{
return (AFortPlayerStateAthena*)GetPlayerState();
}
FGhostModeRepData* GetGhostModeRepData()
{
static auto GhostModeRepDataOffset = GetOffset("GhostModeRepData");
return GetPtr<FGhostModeRepData>(GhostModeRepDataOffset);
}
UAthenaMarkerComponent* GetMarkerComponent()
{
static auto MarkerComponentOffset = GetOffset("MarkerComponent");
return Get<UAthenaMarkerComponent*>(MarkerComponentOffset);
}
static void StartGhostModeHook(UObject* Context, FFrame* Stack, void* Ret); // we could native hook this but eh
static void EndGhostModeHook(AFortPlayerControllerAthena* PlayerController);
static void EnterAircraftHook(UObject* PC, AActor* Aircraft);
static void ServerRequestSeatChangeHook(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex); // actually in zone
static void ServerRestartPlayerHook(AFortPlayerControllerAthena* Controller);

View File

@@ -1,6 +1,7 @@
#include "FortPlayerPawn.h"
#include <memcury.h>
#include "FortPlayerController.h"
#include "FortGadgetItemDefinition.h"
void AFortPlayerPawn::ServerChoosePart(EFortCustomPartType Part, UObject* ChosenCharacterPart)
{
@@ -122,6 +123,36 @@ void AFortPlayerPawn::UnEquipVehicleWeaponDefinition(UFortWeaponItemDefinition*
AFortPlayerController::ServerExecuteInventoryItemHook(PlayerController, PickaxeInstance->GetItemEntry()->GetItemGuid()); // Bad, we should equip the last weapon.
}
void AFortPlayerPawn::StartGhostModeExitHook(UObject* Context, FFrame* Stack, void* Ret)
{
LOG_INFO(LogDev, __FUNCTION__);
auto Pawn = (AFortPlayerPawn*)Context;
auto Controller = Cast<AFortPlayerController>(Pawn->GetController());
if (!Controller)
return;
auto WorldInventory = Controller->GetWorldInventory();
auto SpookyMistItemDefinition = FindObject<UFortGadgetItemDefinition>("/Game/Athena/Items/Gameplay/SpookyMist/AGID_SpookyMist.AGID_SpookyMist");
auto SpookyMistInstance = WorldInventory->FindItemInstance(SpookyMistItemDefinition);
if (SpookyMistInstance)
{
bool bShouldUpdate = false;
WorldInventory->RemoveItem(SpookyMistInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, 1, true);
if (bShouldUpdate)
WorldInventory->Update();
Controller->ApplyCosmeticLoadout();
}
return StartGhostModeExitOriginal(Context, Stack, Ret);
}
AActor* AFortPlayerPawn::ServerOnExitVehicleHook(AFortPlayerPawn* PlayerPawn, ETryExitVehicleBehavior ExitForceBehavior)
{
auto VehicleWeaponDefinition = PlayerPawn->GetVehicleWeaponDefinition(PlayerPawn->GetVehicle());

View File

@@ -32,6 +32,7 @@ class AFortPlayerPawn : public AFortPawn
{
public:
static inline AActor* (*ServerOnExitVehicleOriginal)(AFortPlayerPawn* Pawn, ETryExitVehicleBehavior ExitForceBehavior); // actually returns AFortAthenaVehicle
static inline void (*StartGhostModeExitOriginal)(UObject* Context, FFrame* Stack, void* Ret);
void ServerChoosePart(EFortCustomPartType Part, class UObject* ChosenCharacterPart);
void ForceLaunchPlayerZipline(); // Thanks android
@@ -41,6 +42,7 @@ public:
UFortWeaponItemDefinition* GetVehicleWeaponDefinition(AFortAthenaVehicle* Vehicle);
void UnEquipVehicleWeaponDefinition(UFortWeaponItemDefinition* VehicleWeaponDefinition);
static void StartGhostModeExitHook(UObject* Context, FFrame* Stack, void* Ret); // we could native hook this but eh
static AActor* ServerOnExitVehicleHook(AFortPlayerPawn* Pawn, ETryExitVehicleBehavior ExitForceBehavior); // actually returns AFortAthenaVehicle
static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState);
static void ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, float InFlyTime, FVector InStartDirection, bool bPlayPickupSound);

View File

@@ -2,6 +2,14 @@
#include "FortItemDefinition.h"
enum class EWorldItemDropBehavior : uint8_t
{
DropAsPickup = 0,
DestroyOnDrop = 1,
DropAsPickupDestroyOnEmpty = 2,
EWorldItemDropBehavior_MAX = 3
};
class UFortWorldItemDefinition : public UFortItemDefinition
{
public:
@@ -12,6 +20,12 @@ public:
return ReadBitfieldValue(bCanBeDroppedOffset, bCanBeDroppedFieldMask);
}
EWorldItemDropBehavior& GetDropBehavior()
{
static auto DropBehaviorOffset = GetOffset("DropBehavior");
return Get<EWorldItemDropBehavior>(DropBehaviorOffset);
}
bool ShouldDropOnDeath()
{
static auto bDropOnDeathOffset = GetOffset("bDropOnDeath");

View File

@@ -0,0 +1,56 @@
// FROM 4.23
#pragma once
#include "TypeCompatibleBytes.h"
#if defined(_WIN32) && !defined(_WIN64)
// Don't use inline storage on Win32, because that will affect the alignment of TFunction, and we can't pass extra-aligned types by value on Win32.
#define TFUNCTION_USES_INLINE_STORAGE 0
#elif USE_SMALL_TFUNCTIONS
#define TFUNCTION_USES_INLINE_STORAGE 0
#else
#define TFUNCTION_USES_INLINE_STORAGE 1
#define TFUNCTION_INLINE_SIZE 32
#define TFUNCTION_INLINE_ALIGNMENT 16
#endif
template <typename StorageType, typename FuncType>
struct TFunctionRefBase;
template <typename StorageType, typename Ret, typename... ParamTypes>
struct TFunctionRefBase<StorageType, Ret(ParamTypes...)>
{
Ret(*Callable)(void*, ParamTypes&...);
StorageType Storage;
#if ENABLE_TFUNCTIONREF_VISUALIZATION
// To help debug visualizers
TDebugHelper<void> DebugPtrStorage;
#endif
};
struct FFunctionStorage
{
FFunctionStorage()
: HeapAllocation(nullptr)
{
}
void* HeapAllocation;
#if TFUNCTION_USES_INLINE_STORAGE
// Inline storage for an owned object
TAlignedBytes<TFUNCTION_INLINE_SIZE, TFUNCTION_INLINE_ALIGNMENT> InlineAllocation;
#endif
};
template <bool bUnique>
struct TFunctionStorage : FFunctionStorage
{
};
template <typename FuncType>
class TFunction final : public TFunctionRefBase<TFunctionStorage<false>, FuncType>
{
};

View File

@@ -0,0 +1,16 @@
#pragma once
#include "Object.h"
#include "TimerManager.h"
class UGameInstance :
public UObject
{
public:
inline FTimerManager& GetTimerManager() const
{
static auto TimerManagerOffset = 0x90;
return **(FTimerManager**)(__int64(TimerManagerOffset));
}
};

View File

@@ -7,6 +7,7 @@
#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h"
#include "DataTableFunctionLibrary.h"
#include "FortAthenaMutator_GG.h"
#include "FortAthenaMutator_InventoryOverride.h"
UClass* AGameModeBase::GetDefaultPawnClassForController(AController* InController)
{
@@ -44,16 +45,16 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
if constexpr (bUseSpawnActor)
{
NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParameters);
NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParameters);
}
else
{
struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; }
AGameModeBase_SpawnDefaultPawnAtTransform_Params{ NewPlayer, SpawnTransform };
struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; }
AGameModeBase_SpawnDefaultPawnAtTransform_Params{ NewPlayer, SpawnTransform };
GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params);
GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params);
NewPawn = AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue;
NewPawn = AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue;
}
if (!NewPawn)
@@ -66,12 +67,16 @@ NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParamete
auto NewPlayerAsAthena = Cast<AFortPlayerControllerAthena>(NewPlayer);
auto GameState = ((AFortGameModeAthena*)GameMode)->GetGameStateAthena();
auto PlayerStateAthena = NewPlayerAsAthena->GetPlayerStateAthena();
if (!PlayerStateAthena)
return nullptr;
GET_PLAYLIST(GameState);
if (CurrentPlaylist)
{
CurrentPlaylist->ApplyModifiersToActor(NewPlayerAsAthena->GetPlayerState()); // We need to move this!
CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena); // We need to move this!
}
/* if (Fortnite_Version >= 18)
@@ -90,6 +95,8 @@ NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParamete
if (!WorldInventory->GetPickaxeInstance())
{
// TODO Check Playlist->bRequirePickaxeInStartingInventory
auto CosmeticLoadout = NewPlayerAsAthena->GetCosmeticLoadout();
// LOG_INFO(LogDev, "CosmeticLoadout: {}", __int64(CosmeticLoadout));
auto CosmeticLoadoutPickaxe = CosmeticLoadout ? CosmeticLoadout->GetPickaxe() : nullptr;
@@ -134,6 +141,23 @@ NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParamete
}
} */
auto AddInventoryOverrideTeamLoadouts = [&](AFortAthenaMutator* Mutator)
{
if (auto InventoryOverride = Cast<AFortAthenaMutator_InventoryOverride>(Mutator))
{
auto TeamIndex = PlayerStateAthena->GetTeamIndex();
auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex);
for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++)
{
auto& ItemAndCount = LoadoutContainer.Loadout.at(i);
WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount());
}
}
};
LoopMutators(AddInventoryOverrideTeamLoadouts);
WorldInventory->Update();
}
}

View File

@@ -0,0 +1,2 @@
#pragma once

View File

@@ -0,0 +1,24 @@
#pragma once
#include "Object.h"
/**
* Base class for all interfaces
*
*/
class UInterface : public UObject
{
// DECLARE_CLASS_INTRINSIC(UInterface, UObject, CLASS_Interface | CLASS_Abstract, TEXT("/Script/CoreUObject"))
};
class IInterface
{
protected:
virtual ~IInterface() {}
public:
typedef UInterface UClassType;
};

File diff suppressed because it is too large Load Diff

View File

@@ -155,6 +155,23 @@ bool UObject::IsA(UClass* otherClass)
return false;
}
UFunction* UObject::FindFunction(const std::string& ShortFunctionName)
{
// We could also loop through children.
UClass* super = ClassPrivate;
while (super)
{
if (auto Func = FindObject<UFunction>(super->GetPathName() + "." + ShortFunctionName))
return Func;
super = super->GetSuperStruct();
}
return nullptr;
}
/* class UClass* UObject::StaticClass()
{
static auto Class = FindObject<UClass>("/Script/CoreUObject.Object");

View File

@@ -55,6 +55,7 @@ public:
std::string GetFullName();
bool IsA(UClass* Other);
class UFunction* FindFunction(const std::string& ShortFunctionName);
void* GetProperty(const std::string& ChildName, bool bWarnIfNotFound = true);
void* GetProperty(const std::string& ChildName, bool bWarnIfNotFound = true) const;

View File

@@ -64,3 +64,6 @@ enum class EInternalObjectFlags : int
};
ENUM_CLASS_FLAGS(EInternalObjectFlags)
#define BODY_MACRO_COMBINE_INNER(A,B,C,D) A##B##C##D
#define BODY_MACRO_COMBINE(A,B,C,D) BODY_MACRO_COMBINE_INNER(A,B,C,D)

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -192,6 +192,8 @@
<ClCompile Include="EngineTypes.cpp" />
<ClCompile Include="events.cpp" />
<ClCompile Include="FortAthenaCreativePortal.cpp" />
<ClCompile Include="FortAthenaMutator_Barrier.cpp" />
<ClCompile Include="FortAthenaMutator_Disco.cpp" />
<ClCompile Include="FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp" />
<ClCompile Include="FortAthenaSupplyDrop.cpp" />
<ClCompile Include="FortAthenaVehicle.cpp" />
@@ -257,6 +259,9 @@
<ClInclude Include="Array.h" />
<ClInclude Include="AssertionMacros.h" />
<ClInclude Include="AssetPtr.h" />
<ClInclude Include="AthenaBarrierFlag.h" />
<ClInclude Include="AthenaBarrierObjective.h" />
<ClInclude Include="AthenaBigBaseWall.h" />
<ClInclude Include="AthenaMarkerComponent.h" />
<ClInclude Include="AttributeSet.h" />
<ClInclude Include="BGA.h" />
@@ -282,6 +287,8 @@
<ClInclude Include="Decay.h" />
<ClInclude Include="Delegate.h" />
<ClInclude Include="DelegateBase.h" />
<ClInclude Include="DelegateCombinations.h" />
<ClInclude Include="DelegateInstanceInterface.h" />
<ClInclude Include="die.h" />
<ClInclude Include="EnableIf.h" />
<ClInclude Include="Engine.h" />
@@ -291,8 +298,11 @@
<ClInclude Include="FortAbilitySet.h" />
<ClInclude Include="FortAthenaCreativePortal.h" />
<ClInclude Include="FortAthenaMutator.h" />
<ClInclude Include="FortAthenaMutator_Barrier.h" />
<ClInclude Include="FortAthenaMutator_Disco.h" />
<ClInclude Include="FortAthenaMutator_GG.h" />
<ClInclude Include="FortAthenaMutator_GiveItemsAtGamePhaseStep.h" />
<ClInclude Include="FortAthenaMutator_Heist.h" />
<ClInclude Include="FortAthenaMutator_InventoryOverride.h" />
<ClInclude Include="FortAthenaMutator_InventoryOverride_Bucket.h" />
<ClInclude Include="FortAthenaMutator_ItemDropOnDeath.h" />
@@ -335,6 +345,8 @@
<ClInclude Include="FortWeaponMeleeItemDefinition.h" />
<ClInclude Include="FortWeaponRangedMountedCannon.h" />
<ClInclude Include="FortWorldItemDefinition.h" />
<ClInclude Include="Function.h" />
<ClInclude Include="GameInstance.h" />
<ClInclude Include="GameMode.h" />
<ClInclude Include="GameModeBase.h" />
<ClInclude Include="GameplayAbilitySpec.h" />
@@ -344,12 +356,14 @@
<ClInclude Include="GameSession.h" />
<ClInclude Include="GameState.h" />
<ClInclude Include="GenericPlatformMath.h" />
<ClInclude Include="GenericPlatformMisc.h" />
<ClInclude Include="GenericPlatformTime.h" />
<ClInclude Include="globals.h" />
<ClInclude Include="gui.h" />
<ClInclude Include="hooking.h" />
<ClInclude Include="IdentityFunctor.h" />
<ClInclude Include="inc.h" />
<ClInclude Include="Interface.h" />
<ClInclude Include="IntroSort.h" />
<ClInclude Include="InventoryManagementLibrary.h" />
<ClInclude Include="Invoke.h" />
@@ -390,6 +404,7 @@
<ClInclude Include="RemoveReference.h" />
<ClInclude Include="ReversePredicate.h" />
<ClInclude Include="Rotator.h" />
<ClInclude Include="ScriptDelegates.h" />
<ClInclude Include="ScriptInterface.h" />
<ClInclude Include="Set.h" />
<ClInclude Include="SharedPointer.h" />
@@ -402,9 +417,11 @@
<ClInclude Include="Stack.h" />
<ClInclude Include="StringAssetReference.h" />
<ClInclude Include="Text.h" />
<ClInclude Include="TimerManager.h" />
<ClInclude Include="Transform.h" />
<ClInclude Include="Tuple.h" />
<ClInclude Include="TypeCompatibleBytes.h" />
<ClInclude Include="TypeWrapper.h" />
<ClInclude Include="UnrealMathUtility.h" />
<ClInclude Include="UnrealString.h" />
<ClInclude Include="UnrealTemplate.h" />
@@ -420,6 +437,7 @@
</ItemGroup>
<ItemGroup>
<None Include="DelegateSignatureImpl.inl" />
<None Include="ExpressionParserTypes.inl" />
<None Include="UnrealEngine.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -239,6 +239,12 @@
<ClCompile Include="FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private\Mutators</Filter>
</ClCompile>
<ClCompile Include="FortAthenaMutator_Disco.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private\Mutators</Filter>
</ClCompile>
<ClCompile Include="FortAthenaMutator_Barrier.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private\Mutators</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="log.h" />
@@ -746,6 +752,51 @@
<ClInclude Include="FortAthenaMutator_ItemDropOnDeath.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Mutators</Filter>
</ClInclude>
<ClInclude Include="FortAthenaMutator_Disco.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Mutators</Filter>
</ClInclude>
<ClInclude Include="FortAthenaMutator_Heist.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Mutators</Filter>
</ClInclude>
<ClInclude Include="AthenaBarrierFlag.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building\GameplayActors\Barrier</Filter>
</ClInclude>
<ClInclude Include="AthenaBarrierObjective.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building\GameplayActors\Barrier</Filter>
</ClInclude>
<ClInclude Include="FortAthenaMutator_Barrier.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Mutators</Filter>
</ClInclude>
<ClInclude Include="AthenaBigBaseWall.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building\GameplayActors\Barrier</Filter>
</ClInclude>
<ClInclude Include="Interface.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="TimerManager.h">
<Filter>Engine\Source\Runtime\Engine\Public</Filter>
</ClInclude>
<ClInclude Include="DelegateCombinations.h">
<Filter>Engine\Source\Runtime\Core\Public\Delegates</Filter>
</ClInclude>
<ClInclude Include="ScriptDelegates.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="GenericPlatformMisc.h">
<Filter>Engine\Source\Runtime\Core\Public\GenericPlatform</Filter>
</ClInclude>
<ClInclude Include="Function.h">
<Filter>Engine\Source\Runtime\Core\Public\Templates</Filter>
</ClInclude>
<ClInclude Include="GameInstance.h">
<Filter>Engine\Source\Runtime\Engine\Classes\Engine</Filter>
</ClInclude>
<ClInclude Include="DelegateInstanceInterface.h">
<Filter>Engine\Source\Runtime\Core\Public\Delegates</Filter>
</ClInclude>
<ClInclude Include="TypeWrapper.h">
<Filter>Engine\Source\Runtime\Core\Public\Templates</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Engine">
@@ -913,9 +964,6 @@
<Filter Include="FortniteGame\Source\FortniteGame\Private\Building\GameplayActors">
<UniqueIdentifier>{18a41ed2-b864-4a36-9396-cb0672b8464d}</UniqueIdentifier>
</Filter>
<Filter Include="FortniteGame\Source\FortniteGame\Public\Creative\Minigame">
<UniqueIdentifier>{a28fab04-cc3c-4032-ac3e-22c6b9379312}</UniqueIdentifier>
</Filter>
<Filter Include="FortniteGame\Source\FortniteGame\Private\Creative\Minigame">
<UniqueIdentifier>{7905895d-5ebf-4313-a9de-06f507c35113}</UniqueIdentifier>
</Filter>
@@ -976,6 +1024,15 @@
<Filter Include="FortniteGame\Source\FortniteGame\Public\Mutators">
<UniqueIdentifier>{6efc7bff-2d7b-4fdb-bae8-3d2e736cc82e}</UniqueIdentifier>
</Filter>
<Filter Include="FortniteGame\Source\FortniteGame\Public\Building\GameplayActors\Barrier">
<UniqueIdentifier>{a633ca3f-f699-4c92-8522-e49a14157b95}</UniqueIdentifier>
</Filter>
<Filter Include="FortniteGame\Source\FortniteGame\Public\Creative\Minigame">
<UniqueIdentifier>{a28fab04-cc3c-4032-ac3e-22c6b9379312}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\Source\Runtime\Engine\Public">
<UniqueIdentifier>{3d909143-220c-44b3-819f-79d282c3fc0f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="UnrealEngine.cpp">
@@ -984,5 +1041,8 @@
<None Include="DelegateSignatureImpl.inl">
<Filter>Engine\Source\Runtime\Core\Public\Delegates</Filter>
</None>
<None Include="ExpressionParserTypes.inl">
<Filter>Engine\Source\Runtime\Core\Public\Misc</Filter>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
#pragma once
#include "WeakObjectPtr.h"
template <typename TWeakPtr = FWeakObjectPtr>
class TScriptDelegate
{
public:
TWeakPtr Object;
FName FunctionName;
};

View File

@@ -5,8 +5,8 @@
class FScriptInterface
{
public:
UObject* ObjectPointer;
void* InterfacePointer;
UObject* ObjectPointer = nullptr;
void* InterfacePointer = nullptr;
FORCEINLINE UObject*& GetObjectRef()
{
@@ -17,4 +17,5 @@ public:
template<class InterfaceType>
class TScriptInterface : public FScriptInterface
{
public:
};

View File

@@ -49,7 +49,7 @@ public:
// (GNatives[B])(Context, *this, RESULT_PARAM);
}
__forceinline void StepCompiledIn(void* const Result/*, const FFieldClass* ExpectedPropertyType*/) // https://github.com/EpicGames/UnrealEngine/blob/cdaec5b33ea5d332e51eee4e4866495c90442122/Engine/Source/Runtime/CoreUObject/Public/UObject/Stack.h#L444
__forceinline void StepCompiledIn(void* const Result/*, const FFieldClass* ExpectedPropertyType*/, bool bPrint = false) // https://github.com/EpicGames/UnrealEngine/blob/cdaec5b33ea5d332e51eee4e4866495c90442122/Engine/Source/Runtime/CoreUObject/Public/UObject/Stack.h#L444
{
if (Code)
{
@@ -64,6 +64,9 @@ public:
PropertyChainForCompiledIn = Property->Next;
StepExplicitProperty(Result, Property); */
if (bPrint)
LOG_INFO(LogDev, "No code!");
void* Property = GetPropertyChainForCompiledIn();
GetPropertyChainForCompiledIn() = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next;
StepExplicitProperty(Result, Property);

View File

@@ -0,0 +1,32 @@
#pragma once
#include "EngineTypes.h"
#include "Function.h"
#include "DelegateCombinations.h"
DECLARE_DELEGATE(FTimerDelegate);
struct FTimerUnifiedDelegate
{
/** Holds the delegate to call. */
FTimerDelegate FuncDelegate;
/** Holds the dynamic delegate to call. */
FTimerDynamicDelegate FuncDynDelegate;
/** Holds the TFunction callback to call. */
TFunction<void(void)> FuncCallback;
FTimerUnifiedDelegate() {};
FTimerUnifiedDelegate(FTimerDelegate const& D) : FuncDelegate(D) {};
};
class FTimerManager // : public FNoncopyable
{
public:
FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, FTimerDelegate const& InDelegate, float InRate, bool InbLoop, float InFirstDelay = -1.f)
{
static void (*InternalSetTimerOriginal)(__int64 TimerManager, FTimerHandle& InOutHandle, FTimerUnifiedDelegate&& InDelegate, float InRate, bool InbLoop, float InFirstDelay) =
decltype(InternalSetTimerOriginal)(Addresses::SetTimer);
InternalSetTimerOriginal(__int64(this), InOutHandle, FTimerUnifiedDelegate(InDelegate), InRate, InbLoop, InFirstDelay);
}
};

View File

@@ -0,0 +1,16 @@
#pragma once
template <typename T>
struct TTypeWrapper;
template <typename T>
struct TUnwrapType
{
typedef T Type;
};
template <typename T>
struct TUnwrapType<TTypeWrapper<T>>
{
typedef T Type;
};

View File

@@ -5,6 +5,7 @@
#include "Object.h"
#include "Rotator.h"
#include "Actor.h"
#include "GameInstance.h"
struct FNetworkNotify
{
@@ -46,6 +47,24 @@ public:
return this->Get<T*>(AuthorityGameModeOffset);
}
class AGameState* GetGameState()
{
static auto GameStateOffset = GetOffset("GameState");
return this->Get<class AGameState*>(GameStateOffset);
}
UGameInstance* GetOwningGameInstance()
{
static auto OwningGameInstanceOffset = GetOffset("OwningGameInstance");
return this->Get<UGameInstance*>(OwningGameInstanceOffset);
}
inline FTimerManager& GetTimerManager()
{
return GetOwningGameInstance()->GetTimerManager();
// return (GetOwningGameInstance() ? GetOwningGameInstance()->GetTimerManager() : *TimerManager);
}
template <typename ActorType>
ActorType* SpawnActor(UClass* Class, FTransform UserTransformPtr = FTransform(), const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters())
{

View File

@@ -263,6 +263,9 @@ void Addresses::FindAll()
LOG_INFO(LogDev, "Finding EnterAircraft");
Addresses::EnterAircraft = FindEnterAircraft();
LOG_INFO(LogDev, "Finding SetTimer");
Addresses::SetTimer = FindSetTimer();
LOG_INFO(LogDev, "Finished finding!");
}
@@ -323,6 +326,7 @@ void Addresses::Print()
LOG_INFO(LogDev, "GetInterfaceAddress: 0x{:x}", GetInterfaceAddress - Base);
LOG_INFO(LogDev, "ApplyCharacterCustomization: 0x{:x}", ApplyCharacterCustomization - Base);
LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base);
LOG_INFO(LogDev, "SetTimer: 0x{:x}", SetTimer - Base);
}
void Offsets::FindAll()

View File

@@ -61,6 +61,7 @@ namespace Addresses
extern inline uint64 ApplyCharacterCustomization = 0;
extern inline uint64 GetInterfaceAddress = 0;
extern inline uint64 EnterAircraft = 0;
extern inline uint64 SetTimer = 0;
void SetupVersion(); // Finds Engine Version
void FindAll();

View File

@@ -3,6 +3,7 @@
#include "reboot.h"
#include "FortPlayerControllerAthena.h"
#include "KismetSystemLibrary.h"
#include "AthenaBarrierObjective.h"
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
{

View File

@@ -37,6 +37,7 @@
#include "vendingmachine.h"
#include "FortOctopusVehicle.h"
#include "FortVolumeManager.h"
#include "FortAthenaMutator_Barrier.h"
#include "PlaysetLevelStreamComponent.h"
@@ -464,6 +465,13 @@ DWORD WINAPI Main(LPVOID)
AFortPlayerControllerAthena::ServerReadyToStartMatchHook, (PVOID*)&AFortPlayerControllerAthena::ServerReadyToStartMatchOriginal, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.ServerRequestSeatChange"),
AFortPlayerControllerAthena::ServerRequestSeatChangeHook, (PVOID*)&AFortPlayerControllerAthena::ServerRequestSeatChangeOriginal, false);
if (false)
{
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerGameplay.StartGhostMode"), // (Milxnor) TODO: This changes to a component in later seasons.
AFortPlayerControllerAthena::StartGhostModeHook, (PVOID*)&AFortPlayerControllerAthena::StartGhostModeOriginal, false, true);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerGameplay.EndGhostMode"),
AFortPlayerControllerAthena::EndGhostModeHook, (PVOID*)&AFortPlayerControllerAthena::EndGhostModeOriginal, false);
}
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerGiveCreativeItem"),
AFortPlayerControllerAthena::ServerGiveCreativeItemHook, nullptr, true);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerPlaySquadQuickChatMessage"),
@@ -471,11 +479,8 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland"),
AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"),
AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh
Hooking::MinHook::Hook(FindObject<AFortAthenaMutator_GiveItemsAtGamePhaseStep>("/Script/FortniteGame.Default__FortAthenaMutator_GiveItemsAtGamePhaseStep"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaMutator_GiveItemsAtGamePhaseStep.OnGamePhaseStepChanged"),
AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedHook, (PVOID*)&AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedOriginal, false, true);
// Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"),
// AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh
if (FortOctopusVehicleDefault)
{
@@ -506,6 +511,13 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(FortGameplayAbilityAthena_PeriodicItemGrantDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortGameplayAbilityAthena_PeriodicItemGrant.StartItemAwardTimers"),
UFortGameplayAbilityAthena_PeriodicItemGrant::StartItemAwardTimersHook, (PVOID*)&UFortGameplayAbilityAthena_PeriodicItemGrant::StartItemAwardTimersOriginal, false, true);
Hooking::MinHook::Hook(FindObject<AFortAthenaMutator_Barrier>("/Script/FortniteGame.Default__FortAthenaMutator_Barrier"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaMutator_Barrier.OnGamePhaseStepChanged"),
AFortAthenaMutator_Barrier::OnGamePhaseStepChangedHook, (PVOID*)&AFortAthenaMutator_Barrier::OnGamePhaseStepChangedOriginal, false, true);
Hooking::MinHook::Hook(FindObject<AFortAthenaMutator_Disco>("/Script/FortniteGame.Default__FortAthenaMutator_Disco"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaMutator_Disco.OnGamePhaseStepChanged"),
AFortAthenaMutator_Disco::OnGamePhaseStepChangedHook, (PVOID*)&AFortAthenaMutator_Disco::OnGamePhaseStepChangedOriginal, false, true);
Hooking::MinHook::Hook(FindObject<AFortAthenaMutator_GiveItemsAtGamePhaseStep>("/Script/FortniteGame.Default__FortAthenaMutator_GiveItemsAtGamePhaseStep"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaMutator_GiveItemsAtGamePhaseStep.OnGamePhaseStepChanged"),
AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedHook, (PVOID*)&AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedOriginal, false, true);
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"),
UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true);
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.K2_GiveBuildingResource"),

View File

@@ -659,6 +659,38 @@ static inline uint64 FindSetZoneToIndex() // actually StartNewSafeZonePhase
return 0;
}
static inline uint64 FindSetTimer()
{
auto Addr = Memcury::Scanner::FindStringRef(L"STAT_SetTimer", false).Get();
if (!Addr)
return 0;
for (int i = 0; i < 1000; i++)
{
/* if ((*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x53)
|| (*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x55))
{
return Addr - i;
}
if (Fortnite_Version < 8)
{
if (*(uint8_t*)(uint8_t*)(Addr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x5C)
{
return Addr - i;
}
} */
if (*(uint8_t*)(uint8_t*)(Addr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x8B && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0xC4)
{
return Addr - i;
}
}
return 0;
}
static inline uint64 FindEnterAircraft()
{
auto Addr = Memcury::Scanner::FindStringRef(L"EnterAircraft: [%s] is attempting to enter aircraft after having already exited.", true, 0, Engine_Version >= 500).Get();
@@ -671,7 +703,12 @@ static inline uint64 FindEnterAircraft()
return Addr - i;
}
if (*(uint8_t*)(uint8_t*)(Addr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x5C && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x24)
/* if (*(uint8_t*)(uint8_t*)(Addr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x5C && *(uint8_t*)(uint8_t*)(Addr - i + 3) == 0x24)
{
return Addr - i;
} */
if (*(uint8_t*)(uint8_t*)(Addr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x5C && *(uint8_t*)(uint8_t*)(Addr - i + 3) == 0x74) // 4.1
{
return Addr - i;
}
@@ -744,8 +781,8 @@ static inline uint64 FindApplyGadgetData()
static inline uint64 FindGetInterfaceAddress()
{
if (Engine_Version <= 420)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 FF 48 8B DA 48 8B F1 48").Get(); // 4.1
if (Engine_Version <= 421)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 FF 48 8B DA 48 8B F1 48").Get(); // 4.1 & 6.21
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 DB 48 8B FA 48 8B F1 48 85 D2 0F 84 ? ? ? ? 8B 82 ? ? ? ? C1 E8").Get();
}

View File

@@ -22,6 +22,7 @@
#include <fstream>
#include <olectl.h>
#include "FortAthenaMutator_Disco.h"
#include "globals.h"
#include "Fonts/ruda-bold.h"
#include "Vector.h"
@@ -36,6 +37,7 @@
#include "FortGadgetItemDefinition.h"
#include "FortWeaponItemDefinition.h"
#include "events.h"
#include "FortAthenaMutator_Heist.h"
#define GAME_TAB 1
#define PLAYERS_TAB 2
@@ -45,8 +47,9 @@
#define LATEGAME_TAB 6
#define DUMP_TAB 7
#define UNBAN_TAB 8
#define SETTINGS_TAB 9
#define CREDITS_TAB 10
#define DEVELOPER_TAB 9
#define SETTINGS_TAB 10
#define CREDITS_TAB 11
#define MAIN_PLAYERTAB 1
#define INVENTORY_PLAYERTAB 2
@@ -216,6 +219,10 @@ static int playerTabTab = MAIN_PLAYERTAB;
void StaticUI()
{
#ifndef PROD
ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent);
#endif
ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo);
ImGui::Checkbox("Infinite Materials", &Globals::bInfiniteMaterials);
@@ -306,6 +313,16 @@ void MainTabs()
// maybe a Replication Stats for >3.3?
#ifndef PROD
if (ImGui::BeginTabItem("Developer"))
{
Tab = DEVELOPER_TAB;
PlayerTab = -1;
bInformationTab = false;
ImGui::EndTabItem();
}
#endif
if (false && ImGui::BeginTabItem(("Credits")))
{
Tab = CREDITS_TAB;
@@ -365,9 +382,7 @@ void MainUI()
if (bLoaded)
{
StaticUI();
#ifndef PROD
ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent);
#endif
if (!bStartedBus)
{
bool bWillBeLategame = Globals::bLateGame.load();
@@ -441,6 +456,44 @@ void MainUI()
}
}
if (ImGui::Button("TEST"))
{
auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode();
auto GameState = GameMode->GetGameState();
static auto mutatorClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass);
for (int i = 0; i < AllMutators.Num(); i++)
{
auto Mutator = AllMutators.at(i);
LOG_INFO(LogDev, "[{}] Mutator: {}", i, Mutator->GetFullName());
if (auto DiscoMutator = Cast<AFortAthenaMutator_Disco>(Mutator))
{
auto& ControlPointSpawnData = DiscoMutator->GetControlPointSpawnData();
LOG_INFO(LogDev, "ControlPointSpawnData.Num(): {}", ControlPointSpawnData.Num());
}
else if (auto HeistMutator = Cast<AFortAthenaMutator_Heist>(Mutator))
{
auto& HeistExitCraftSpawnData = HeistMutator->GetHeistExitCraftSpawnData();
LOG_INFO(LogDev, "HeistExitCraftSpawnData.Num(): {}", HeistExitCraftSpawnData.Num());
for (int j = 0; j < HeistExitCraftSpawnData.Num(); j++)
{
auto& CurrentHeistExitCraftSpawnData = HeistExitCraftSpawnData.at(j);
auto CurveTable = CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().CurveTable;
// LOG_INFO(LogDev, "{} {}", CurveTable ? CurveTable->GetFullName() : "InvalidTable",
// CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().RowName.IsValid() ? CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().RowName.ToString() : "InvalidName");
}
}
}
}
if (!bStartedBus)
{
if (Globals::bLateGame.load())
@@ -743,6 +796,22 @@ void MainUI()
else if (Tab == UNBAN_TAB)
{
}
else if (Tab == DEVELOPER_TAB)
{
static std::string ClassNameToDump;
ImGui::InputText("Class Name to get VFT", &ClassNameToDump);
if (ImGui::Button("Print Class VFT"))
{
auto ClassToDump = FindObject<UClass>(ClassNameToDump)->CreateDefaultObject();
if (ClassToDump)
{
LOG_INFO(LogDev, "{} VFT: 0x{:x}", ClassToDump->GetName(), __int64(ClassToDump->VFTable) - __int64(GetModuleHandleW(0)));
}
}
}
else if (Tab == SETTINGS_TAB)
{

View File

@@ -377,7 +377,7 @@ static void CopyStruct(void* Dest, void* Src, size_t Size, UStruct* Struct = nul
}
template <typename T = __int64>
static T* Alloc(size_t Size, bool bUseRealloc = false)
static T* Alloc(size_t Size = sizeof(T), bool bUseRealloc = false)
{
return bUseRealloc ? (T*)FMemory::Realloc(0, Size, 0) : (T*)VirtualAlloc(0, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}