This commit is contained in:
Milxnor
2023-03-11 23:30:19 -05:00
parent 07950d84a2
commit ea7086c85f
28 changed files with 714 additions and 125 deletions

View File

@@ -11,8 +11,11 @@ struct PadHexB0 { char Pad[0xB0]; };
// using FPredictionKey = PadHex18;
// using FGameplayEventData = PadHexA8;
// using FPredictionKey = PadHex10;
using FGameplayEventData = PadHexB0;
using FPredictionKey = __int64;
using FGameplayEventData = __int64;
// using FGameplayEventData = __int64;
class UAbilitySystemComponent : public UObject
{
@@ -32,7 +35,10 @@ public:
FGameplayAbilitySpecHandle GiveAbilityEasy(UClass* AbilityClass);
FGameplayAbilitySpec* FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle);
static void ServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, FPredictionKey PredictionKey);
static void ServerTryActivateAbilityWithEventDataHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, FPredictionKey PredictionKey, FGameplayEventData TriggerEventData);
static void ServerTryActivateAbilityHook1(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex10 PredictionKey);
static void ServerTryActivateAbilityHook2(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex18 PredictionKey);
static void ServerTryActivateAbilityWithEventDataHook1(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex10 PredictionKey, FGameplayEventData TriggerEventData);
static void ServerTryActivateAbilityWithEventDataHook2(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex18 PredictionKey, FGameplayEventData TriggerEventData);
static void ServerAbilityRPCBatchHook(UAbilitySystemComponent* AbilitySystemComponent, __int64 BatchInfo);
};

View File

@@ -7,7 +7,7 @@ void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<vo
auto ActivatableAbilities = AbilitySystemComponent->GetPtr<FFastArraySerializer>(ActivatableAbilitiesOffset);
static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items");
auto Items = (TArray<__int64>*)(__int64(ActivatableAbilities) + ItemsOffset);
auto Items = (TArray<FGameplayAbilitySpec>*)(__int64(ActivatableAbilities) + ItemsOffset);
static auto SpecSize = FGameplayAbilitySpec::GetStructSize();
@@ -15,7 +15,7 @@ void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<vo
{
for (int i = 0; i < Items->Num(); i++)
{
auto CurrentSpec = (FGameplayAbilitySpec*)(__int64(Items->Data) + (static_cast<long long>(SpecSize) * i));
auto CurrentSpec = Items->AtPtr(i, SpecSize); // (FGameplayAbilitySpec*)(__int64(Items->Data) + (static_cast<long long>(SpecSize) * i));
func(CurrentSpec);
}
}
@@ -62,20 +62,20 @@ void InternalServerTryActivateAbility(UAbilitySystemComponent* AbilitySystemComp
else
LOG_ERROR(LogAbilities, "Prediction key size does not match with any of them!");
if (res)
if (!res)
{
LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Rejecting ClientActivation of {}. InternalTryActivateAbility failed: ", AbilityToActivate->GetName());
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
SetBitfield(Spec, 1, false); // InputPressed = false
static auto ActivatableAbilitiesOffset = AbilitySystemComponent->GetOffset("ActivatableAbilities");
AbilitySystemComponent->Get<FFastArraySerializer>(ActivatableAbilitiesOffset).MarkItemDirty(Spec);
}
else
{
LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Activated {}", AbilityToActivate->GetName());
}
static auto ActivatableAbilitiesOffset = AbilitySystemComponent->GetOffset("ActivatableAbilities");
AbilitySystemComponent->Get<FFastArraySerializer>(ActivatableAbilitiesOffset).MarkItemDirty(Spec); // we only need to do this if the ability fails but eh
}
FGameplayAbilitySpecHandle UAbilitySystemComponent::GiveAbilityEasy(UClass* AbilityClass)
@@ -112,19 +112,30 @@ FGameplayAbilitySpec* UAbilitySystemComponent::FindAbilitySpecFromHandle(FGamepl
return SpecToReturn;
}
void UAbilitySystemComponent::ServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent,
FGameplayAbilitySpecHandle Handle, bool InputPressed, FPredictionKey PredictionKey)
void UAbilitySystemComponent::ServerTryActivateAbilityHook1(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex10 PredictionKey)
{
LOG_INFO(LogAbilities, "ServerTryActivateAbility");
InternalServerTryActivateAbility(AbilitySystemComponent, Handle, /* InputPressed, */ &PredictionKey, nullptr);
LOG_INFO(LogAbilities, "ServerTryActivateAbility1");
InternalServerTryActivateAbility(AbilitySystemComponent, Handle, /* InputPressed, */ (FPredictionKey*)&PredictionKey, nullptr);
}
void UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook(UAbilitySystemComponent* AbilitySystemComponent,
FGameplayAbilitySpecHandle Handle, bool InputPressed, FPredictionKey PredictionKey, FGameplayEventData TriggerEventData)
void UAbilitySystemComponent::ServerTryActivateAbilityHook2(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex18 PredictionKey)
{
LOG_INFO(LogAbilities, "ServerTryActivateAbilityWithEventData");
LOG_INFO(LogAbilities, "ServerTryActivateAbility2");
InternalServerTryActivateAbility(AbilitySystemComponent, Handle, /* InputPressed, */ (FPredictionKey*)&PredictionKey, nullptr);
}
void UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook1(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex10 PredictionKey, FGameplayEventData TriggerEventData)
{
LOG_INFO(LogAbilities, "ServerTryActivateAbilityWithEventData1");
InternalServerTryActivateAbility(AbilitySystemComponent, Handle, /* InputPressed, */
&PredictionKey, &TriggerEventData);
(FPredictionKey*)&PredictionKey, &TriggerEventData);
}
void UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook2(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, PadHex18 PredictionKey, FGameplayEventData TriggerEventData)
{
LOG_INFO(LogAbilities, "ServerTryActivateAbilityWithEventData2");
InternalServerTryActivateAbility(AbilitySystemComponent, Handle, /* InputPressed, */
(FPredictionKey*)&PredictionKey, &TriggerEventData);
}
void UAbilitySystemComponent::ServerAbilityRPCBatchHook(UAbilitySystemComponent* AbilitySystemComponent, __int64 BatchInfo)

View File

@@ -43,6 +43,17 @@ UActorComponent* AActor::GetComponentByClass(class UClass* ComponentClass)
return AActor_GetComponentByClass_Params.ReturnValue;
}
float AActor::GetDistanceTo(AActor* OtherActor)
{
static auto fn = FindObject<UFunction>("/Script/Engine.Actor.GetDistanceTo");
struct { AActor* OtherActor; float ReturnValue; } AActor_GetDistanceTo_Params{OtherActor};
this->ProcessEvent(fn, &AActor_GetDistanceTo_Params);
return AActor_GetDistanceTo_Params.ReturnValue;
}
FVector AActor::GetActorLocation()
{
static auto K2_GetActorLocationFn = FindObject<UFunction>("/Script/Engine.Actor.K2_GetActorLocation");

View File

@@ -12,4 +12,5 @@ public:
struct FVector GetActorRightVector();
void K2_DestroyActor();
class UActorComponent* GetComponentByClass(class UClass* ComponentClass);
float GetDistanceTo(AActor* OtherActor);
};

View File

@@ -61,7 +61,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
auto DamageThatWillAffect = Damage;
auto skid = Out / (BuildingSMActor->GetMaxHealth() / DamageThatWillAffect);
float skid = Out / (BuildingSMActor->GetMaxHealth() / DamageThatWillAffect);
ResourceCount = round(skid); // almost right
}

View File

@@ -33,8 +33,17 @@ public:
void SetTeam(unsigned char InTeam)
{
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.SetTeam");
if (!fn)
{
static auto TeamOffset = GetOffset("Team");
Get<uint8_t>(TeamOffset) = InTeam;
}
else
{
this->ProcessEvent(fn, &InTeam);
}
}
static inline void (*OnDamageServerOriginal)(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,

View File

@@ -42,11 +42,21 @@ void ShowFoundation(UObject* BuildingFoundation)
if (!BuildingFoundation)
return;
SetBitfield(BuildingFoundation->GetPtr<PlaceholderBitfield>("bServerStreamedInLevel"), 2, true);
static auto bServerStreamedInLevelFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bServerStreamedInLevel"));
static auto bServerStreamedInLevelOffset = BuildingFoundation->GetOffset("bServerStreamedInLevel");
BuildingFoundation->SetBitfieldValue(bServerStreamedInLevelOffset, bServerStreamedInLevelFieldMask, true);
static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType");
BuildingFoundation->Get<uint8_t>(DynamicFoundationTypeOffset) = true ? 0 : 3;
static auto bShowHLODWhenDisabledOffset = BuildingFoundation->GetOffset("bShowHLODWhenDisabled", false);
if (bShowHLODWhenDisabledOffset != 0)
{
static auto bShowHLODWhenDisabledFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bShowHLODWhenDisabled"));
BuildingFoundation->SetBitfieldValue(bShowHLODWhenDisabledOffset, bShowHLODWhenDisabledFieldMask, true);
}
static auto OnRep_ServerStreamedInLevelFn = FindObject<UFunction>("/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel");
BuildingFoundation->ProcessEvent(OnRep_ServerStreamedInLevelFn);
@@ -54,7 +64,7 @@ void ShowFoundation(UObject* BuildingFoundation)
if (DynamicFoundationRepDataOffset != 0)
{
auto DynamicFoundationRepData = BuildingFoundation->GetPtr(DynamicFoundationRepDataOffset);
auto DynamicFoundationRepData = BuildingFoundation->GetPtr<void>(DynamicFoundationRepDataOffset);
static auto EnabledStateOffset = FindOffsetStruct("/Script/FortniteGame.DynamicBuildingFoundationRepData", "EnabledState");
@@ -178,6 +188,21 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
(*(int*)(__int64(CurrentPlaylistInfo) + PlaylistReplicationKeyOffset))++;
CurrentPlaylistInfo->MarkArrayDirty();
auto aeuh = *(UObject**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset);
if (aeuh)
{
if (Fortnite_Version >= 13)
{
static auto LastSafeZoneIndexOffset = aeuh->GetOffset("LastSafeZoneIndex");
if (LastSafeZoneIndexOffset != -1)
{
*(int*)(__int64(aeuh) + LastSafeZoneIndexOffset) = 0;
}
}
}
GameState->OnRep_CurrentPlaylistInfo();
}
else
@@ -289,7 +314,14 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
ShowFoundation(TheBlock);
}
if (Fortnite_Version == 17.50f) {
if (Fortnite_Version == 14.60 && Globals::bGoingToPlayEvent)
{
auto aircraftcarrier = FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation3");
LOG_INFO(LogDev, "aircraftcarrier: {}", __int64(aircraftcarrier));
ShowFoundation(aircraftcarrier);
}
if (Fortnite_Version == 17.50) {
auto FarmAfter = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.farmbase_2"));
ShowFoundation(FarmAfter);
@@ -297,7 +329,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
ShowFoundation(FarmPhase);
}
if (Fortnite_Version == 17.40f) {
if (Fortnite_Version == 17.40) {
auto AbductedCoral = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.CoralPhase_02")); // Coral Castle Phases (CoralPhase_01, CoralPhase_02 and CoralPhase_03)
ShowFoundation(AbductedCoral);
@@ -320,7 +352,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
ShowFoundation(CoralFoundation_17);
}
if (Fortnite_Version == 17.30f) {
if (Fortnite_Version == 17.30) {
auto AbductedSlurpy = FindObject(("LF_Athena_POI_50x50_C /Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.Slurpy_Phase03")); // Slurpy Swamp Phases (Slurpy_Phase01, Slurpy_Phase02 and Slurpy_Phase03)
ShowFoundation(AbductedSlurpy);
}
@@ -358,7 +390,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (PlaylistToUse)
{
static auto AdditionalLevelsOffset = PlaylistToUse->GetOffset("AdditionalLevels");
static auto AdditionalLevelsOffset = PlaylistToUse->GetOffset("AdditionalLevels", false);
if (AdditionalLevelsOffset != 0)
{
auto& AdditionalLevels = PlaylistToUse->Get<TArray<TSoftObjectPtr<UClass>>>(AdditionalLevelsOffset);
LOG_INFO(LogPlaylist, "Loading {} playlist levels.", AdditionalLevels.Num());
@@ -373,6 +408,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
}
}
}
SetBitfield(GameMode->GetPtr<PlaceholderBitfield>("bWorldIsReady"), 1, true);
}
@@ -409,7 +445,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
}
/*
static auto FortPlayerStartWarmupClass = FindObject<UClass>("/Script/FortniteGame.FortPlayerStartWarmup");
TArray<AActor*> Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortPlayerStartWarmupClass);
@@ -419,7 +454,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (ActorsNum == 0)
return false;
*/
static int LastNum9 = 1;
@@ -431,11 +465,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static auto MapInfoOffset = GameState->GetOffset("MapInfo");
auto MapInfo = GameState->Get(MapInfoOffset);
if (!MapInfo)
if (!MapInfo && Engine_Version >= 421)
return false;
static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos");
// if (GameState->GetPlayersLeft() < GameMode->Get<int>("WarmupRequiredPlayerCount"))
// if (!bFirstPlayerJoined)
// return false;
@@ -460,6 +492,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
GameState->Get<float>("WarmupCountdownStartTime") = TimeSeconds;
GameMode->Get<float>("WarmupEarlyCountdownDuration") = EarlyDuration;
/*
auto AllMegaStormManagers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), GameMode->Get<UClass*>("MegaStormManagerClass"));
LOG_INFO(LogDev, "AllMegaStormManagers.Num() {}", AllMegaStormManagers.Num());
@@ -475,10 +508,11 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
LOG_INFO(LogDev, "MegaStormManager->GetMegaStormCircles().Num() {}", MegaStormManager->GetMegaStormCircles().Num());
}
}
*/
// GameState->Get<bool>("bGameModeWillSkipAircraft") = Globals::bGoingToPlayEvent && Fortnite_Version == 17.30;
if (Engine_Version < 424)
// if (Engine_Version < 424)
GameState->OnRep_CurrentPlaylistInfo(); // ?
// SetupNavConfig();
@@ -490,16 +524,21 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
{
if (GameState->GetPlayersLeft() >= GameMode->Get<int>("WarmupRequiredPlayerCount"))
{
if (MapInfo)
{
static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos");
if (MapInfo->Get<TArray<__int64>>(FlightInfosOffset).ArrayNum <= 0)
return true;
}
}
}
/* static auto TeamsOffset = GameState->GetOffset("Teams");
static auto TeamsOffset = GameState->GetOffset("Teams");
auto& Teams = GameState->Get<TArray<UObject*>>(TeamsOffset);
if (Teams.Num() <= 0)
return false; */
return false;
static int LastNum3 = 1;
@@ -521,8 +560,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller)
{
LOG_INFO(LogTeam, "PickTeam called!");
static auto NextTeamIndex = 3;
return ++NextTeamIndex;
return NextTeamIndex;
}
void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor)
@@ -544,8 +584,12 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
GameState->OnRep_GamePhase();
}
if (false)
static bool bSpawnedFloorLoot = false;
if (!bSpawnedFloorLoot)
{
bSpawnedFloorLoot = true;
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");
@@ -621,8 +665,9 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
if (Globals::bNoMCP)
{
static auto CharacterPartsOffset = PlayerStateAthena->GetOffset("CharacterParts", false);
static auto CustomCharacterPartsStruct = FindObject<UStruct>("/Script/FortniteGame.CustomCharacterParts");
if (CharacterPartsOffset != 0)
if (CharacterPartsOffset != 0) // && CustomCharacterPartsStruct)
{
auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts");
@@ -700,11 +745,11 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
};
FUniqueNetIdReplExperimental bugha{};
auto& PlayerStateUniqueId = bugha; // PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId");
auto& PlayerStateUniqueId = PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId");
// if (false)
// if (GameMemberInfoArrayOffset != 0)
if (Engine_Version >= 423 && false)
if (Engine_Version >= 423)
{
struct FGameMemberInfo : public FFastArraySerializerItem
{
@@ -818,7 +863,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
}
}
static auto SpawnActorDataListOffset = GameMode->GetOffset("SpawnActorDataList");
static auto SpawnActorDataListOffset = GameMode->GetOffset("SpawnActorDataList", false);
if (SpawnActorDataListOffset != 0)
{

View File

@@ -25,6 +25,9 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
if (NewItemInstance)
{
if (LoadedAmmo != -1)
NewItemInstance->GetItemEntry()->GetLoadedAmmo() = LoadedAmmo;
NewItemInstances.push_back(NewItemInstance);
// NewItemInstance->GetItemEntry()->GetItemDefinition() = ItemDefinition;
@@ -74,8 +77,8 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
return true;
}
static auto FortItemEntryStruct = FindObject(L"/Script/FortniteGame.FortItemEntry");
static auto FortItemEntrySize = *(int*)(__int64(FortItemEntryStruct) + Offsets::PropertiesSize);
static auto FortItemEntryStruct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntry");
static auto FortItemEntrySize = FortItemEntryStruct->GetPropertiesSize();
auto& ItemInstances = GetItemList().GetItemInstances();
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();
@@ -91,7 +94,7 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
for (int i = 0; i < ReplicatedEntries.Num(); i++)
{
if (ReplicatedEntries.at(i).GetItemGuid() == ItemGuid)
if (ReplicatedEntries.at(i, FortItemEntrySize).GetItemGuid() == ItemGuid)
{
ReplicatedEntries.Remove(i, FortItemEntrySize);
break;
@@ -134,6 +137,21 @@ void AFortInventory::ModifyCount(UFortItem* ItemInstance, int New, bool bRemove,
}
}
UFortItem* AFortInventory::FindItemInstance(UFortItemDefinition* ItemDefinition)
{
auto& ItemInstances = GetItemList().GetItemInstances();
for (int i = 0; i < ItemInstances.Num(); i++)
{
auto ItemInstance = ItemInstances.At(i);
if (ItemInstance->GetItemEntry()->GetItemDefinition() == ItemDefinition)
return ItemInstance;
}
return nullptr;
}
UFortItem* AFortInventory::FindItemInstance(const FGuid& Guid)
{
auto& ItemInstances = GetItemList().GetItemInstances();
@@ -151,11 +169,14 @@ UFortItem* AFortInventory::FindItemInstance(const FGuid& Guid)
FFortItemEntry* AFortInventory::FindReplicatedEntry(const FGuid& Guid)
{
static auto FortItemEntryStruct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntry");
static auto FortItemEntrySize = FortItemEntryStruct->GetPropertiesSize();
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();
for (int i = 0; i < ReplicatedEntries.Num(); i++)
{
auto& ReplicatedEntry = ReplicatedEntries.At(i);
auto& ReplicatedEntry = ReplicatedEntries.At(i, FortItemEntrySize);
if (ReplicatedEntry.GetItemGuid() == Guid)
return &ReplicatedEntry;

View File

@@ -95,6 +95,8 @@ public:
bool RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count);
void ModifyCount(UFortItem* ItemInstance, int New, bool bRemove = false, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries = nullptr, bool bUpdate = true);
UFortItem* FindItemInstance(UFortItemDefinition* ItemDefinition);
UFortItem* FindItemInstance(const FGuid& Guid);
FFortItemEntry* FindReplicatedEntry(const FGuid& Guid);
};

View File

@@ -1,4 +1,5 @@
#include "FortKismetLibrary.h"
#include "ScriptInterface.h"
UFortResourceItemDefinition* UFortKismetLibrary::K2_GetResourceItemDefinition(EFortResourceType ResourceType)
{
@@ -40,6 +41,10 @@ void UFortKismetLibrary::ApplyCharacterCosmetics(UObject* WorldContextObject, co
{
auto CharacterPartsPS = PlayerState->GetPtr<__int64>("CharacterParts");
static auto CustomCharacterPartsStruct = FindObject<UStruct>("/Script/FortniteGame.CustomCharacterParts");
// if (CustomCharacterPartsStruct)
{
static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts");
auto Parts = (UObject**)(__int64(CharacterPartsPS) + PartsOffset); // UCustomCharacterPart* Parts[0x6]
@@ -51,12 +56,114 @@ void UFortKismetLibrary::ApplyCharacterCosmetics(UObject* WorldContextObject, co
static auto OnRep_CharacterPartsFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts");
PlayerState->ProcessEvent(OnRep_CharacterPartsFn);
}
}
else
{
// TODO Add character data support
}
}
void UFortKismetLibrary::GiveItemToInventoryOwnerHook(UObject* Context, FFrame& Stack, void* Ret)
{
auto Params = /*(UFortKismetLibrary_GiveItemToInventoryOwner_Params*)*/Stack.Locals;
static auto InventoryOwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "InventoryOwner");
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "ItemDefinition");
static auto NumberToGiveOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "NumberToGive");
static auto bNotifyPlayerOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "bNotifyPlayer");
static auto ItemLevelOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "ItemLevel");
static auto PickupInstigatorHandleOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "PickupInstigatorHandle");
auto InventoryOwner = *(TScriptInterface<UFortInventoryOwnerInterface>*)(__int64(Params) + InventoryOwnerOffset);
auto ItemDefinition = *(UFortWorldItemDefinition**)(__int64(Params) + ItemDefinitionOffset);
auto NumberToGive = *(int*)(__int64(Params) + NumberToGiveOffset);
auto bNotifyPlayer = *(bool*)(__int64(Params) + bNotifyPlayerOffset);
auto ItemLevel = *(int*)(__int64(Params) + ItemLevelOffset);
auto PickupInstigatorHandle = *(int*)(__int64(Params) + PickupInstigatorHandleOffset);
auto InterfacePointer = InventoryOwner.InterfacePointer;
LOG_INFO(LogDev, "InterfacePointer: {}", __int64(InterfacePointer));
if (!InterfacePointer)
return;
auto ObjectPointer = InventoryOwner.ObjectPointer;
if (!ObjectPointer)
return;
// LOG_INFO(LogDev, "ObjectPointer Name: {}", ObjectPointer->GetFullName());
return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret);
}
void UFortKismetLibrary::K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret)
{
struct UFortKismetLibrary_K2_RemoveItemFromPlayer_Params
{
AFortPlayerController* PlayerController; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UFortWorldItemDefinition* ItemDefinition; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int AmountToRemove; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
bool bForceRemoval; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
auto Params = /*(UFortKismetLibrary_K2_RemoveItemFromPlayer_Params*)*/Stack.Locals;
static auto PlayerControllerOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer", "PlayerController");
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer", "ItemDefinition");
static auto AmountToRemoveOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer", "AmountToRemove");
auto PlayerController = *(AFortPlayerController**)(__int64(Params) + PlayerControllerOffset);
auto ItemDefinition = *(UFortWorldItemDefinition**)(__int64(Params) + ItemDefinitionOffset);
auto AmountToRemove = *(int*)(__int64(Params) + AmountToRemoveOffset);
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return;
auto ItemInstance = WorldInventory->FindItemInstance(ItemDefinition);
if (!ItemInstance)
return;
bool bShouldUpdate = false;
WorldInventory->RemoveItem(ItemInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, AmountToRemove);
if (bShouldUpdate)
WorldInventory->Update();
return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret);
}
void UFortKismetLibrary::K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret)
{
struct UFortKismetLibrary_K2_GiveItemToPlayer_Params
{
AFortPlayerController* PlayerController; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UFortWorldItemDefinition* ItemDefinition; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int NumberToGive; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
bool bNotifyPlayer; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
auto Params = (UFortKismetLibrary_K2_GiveItemToPlayer_Params*)Stack.Locals;
auto PlayerController = Params->PlayerController;
auto ItemDefinition = Params->ItemDefinition;
auto NumberToGive = Params->NumberToGive;
auto bNotifyPlayer = Params->bNotifyPlayer;
bool bShouldUpdate = false;
PlayerController->GetWorldInventory()->AddItem(ItemDefinition, &bShouldUpdate, NumberToGive, -1, bNotifyPlayer);
if (bShouldUpdate)
PlayerController->GetWorldInventory()->Update();
return K2_GiveItemToPlayerOriginal(Context, Stack, Ret);
}
UClass* UFortKismetLibrary::StaticClass()
{
static auto ptr = FindObject<UClass>(L"/Script/FortniteGame.FortKismetLibrary");

View File

@@ -3,13 +3,24 @@
#include "Object.h"
#include "FortResourceItemDefinition.h"
#include "FortPlayerController.h"
#include "BuildingSMActor.h"
class UFortKismetLibrary : public UObject
{
public:
using UFortInventoryOwnerInterface = UObject;
static inline void (*K2_GiveItemToPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static inline void (*K2_RemoveItemFromPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static inline void (*GiveItemToInventoryOwnerOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static UFortResourceItemDefinition* K2_GetResourceItemDefinition(EFortResourceType ResourceType);
static void ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray<UObject*>& CharacterParts, UObject* PlayerState, bool* bSuccess);
static void GiveItemToInventoryOwnerHook(UObject* Context, FFrame& Stack, void* Ret);
static void K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret);
static void K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret);
static UClass* StaticClass();
};

View File

@@ -86,8 +86,8 @@ std::vector<std::pair<UFortItemDefinition*, int>> PickLootDrops(FName TierGroupN
{
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"));
LTDTables.push_back(LoadObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client"));
LPTables.push_back(LoadObject<UDataTable>(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client"));
}
std::vector<FFortLootTierData*> TierGroupLTDs;
@@ -104,11 +104,16 @@ std::vector<std::pair<UFortItemDefinition*, int>> PickLootDrops(FName TierGroupN
// auto TierGroupNameStr = TierGroupName.ToString();
// LOG_INFO(LogLoot, "LTDRowMapNum: {}", LTDRowMapNum);
for (int i = 0; i < LTDRowMapNum; i++)
{
auto& CurrentLTD = LTDRowMap.Pairs.Elements[i].ElementData.Value;
auto TierData = (FFortLootTierData*)CurrentLTD.Value();
if (IsBadReadPtr(TierData, 8))
continue;
// auto TierDataGroupStr = TierData->TierGroup.ToString();
// std::cout << "TierData->TierGroup.ToString(): " << TierDataGroupStr << '\n';
@@ -148,7 +153,10 @@ std::vector<std::pair<UFortItemDefinition*, int>> PickLootDrops(FName TierGroupN
return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm
int MinimumLootDrops = 0;
float NumLootPackageDrops = std::floor(ChosenRowLootTierData->GetNumLootPackageDrops());
static int AmountToAdd = Engine_Version >= 424 ? 1 : 0; // fr
float NumLootPackageDrops = std::floor(ChosenRowLootTierData->GetNumLootPackageDrops() + AmountToAdd);
if (LootPackageCategoryMinArray.ArrayNum)
{
@@ -252,9 +260,7 @@ std::vector<std::pair<UFortItemDefinition*, int>> PickLootDrops(FName TierGroupN
std::cout << "b: " << b << '\n'; */
}
static int AmountToAdd = Engine_Version >= 424 ? 1 : 0; // fr
LootDrops.reserve(NumLootPackageDrops + AmountToAdd);
LootDrops.reserve(NumLootPackageDrops);
for (float i = 0; i < NumLootPackageDrops; i++)
{

View File

@@ -87,6 +87,10 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
auto& CurrentItemGuid = Pickup->GetPickupLocationData()->GetPickupGuid(); // Pawn->CurrentWeapon->ItemEntryGuid;
auto ItemInstanceToSwap = WorldInventory->FindItemInstance(CurrentItemGuid);
if (!ItemInstanceToSwap)
return CompletePickupAnimationOriginal(Pickup);
auto ItemEntryToSwap = ItemInstanceToSwap->GetItemEntry();
auto ItemDefinitionToSwap = ItemEntryToSwap ? Cast<UFortWorldItemDefinition>(ItemEntryToSwap->GetItemDefinition()) : nullptr;
bool bHasSwapped = false;
@@ -137,7 +141,6 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
if (CurrentItemEntry->GetItemDefinition() == PickupItemDefinition)
{
if (CurrentItemEntry->GetCount() < PickupItemDefinition->GetMaxStackSize())
{
int OverStack = CurrentItemEntry->GetCount() + cpyCount - PickupItemDefinition->GetMaxStackSize();

View File

@@ -15,6 +15,7 @@
#include "FortLootPackage.h"
#include "FortPickup.h"
#include "FortPlayerPawn.h"
#include <memcury.h>
void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot)
{
@@ -160,12 +161,17 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController*
// PC->ServerRestartPlayer();
}
void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData)
void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret)
{
auto PlayerController = Cast<AFortPlayerController>(Context);
if (!PlayerController) // ??
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
auto PlayerStateAthena = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerStateAthena)
return;
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
UClass* BuildingClass = nullptr;
FVector BuildLocation;
@@ -174,9 +180,11 @@ void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController*
if (Fortnite_Version >= 8.30)
{
BuildLocation = CreateBuildingData.BuildLoc;
BuildRotator = CreateBuildingData.BuildRot;
bMirrored = CreateBuildingData.bMirrored;
auto CreateBuildingData = (FCreateBuildingActorData*)Stack->Locals;
BuildLocation = CreateBuildingData->BuildLoc;
BuildRotator = CreateBuildingData->BuildRot;
bMirrored = CreateBuildingData->bMirrored;
static auto BroadcastRemoteClientInfoOffset = PlayerController->GetOffset("BroadcastRemoteClientInfo");
auto BroadcastRemoteClientInfo = PlayerController->Get(BroadcastRemoteClientInfoOffset);
@@ -186,13 +194,21 @@ void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController*
}
else
{
struct FBuildingClassData { UClass* BuildingClass; int PreviousBuildingLevel; int UpgradeLevel; };
struct SCBAParams { FBuildingClassData BuildingClassData; FVector BuildLoc; FRotator BuildRot; bool bMirrored; };
auto Params = (SCBAParams*)Stack->Locals;
BuildingClass = Params->BuildingClassData.BuildingClass;
BuildLocation = Params->BuildLoc;
BuildRotator = Params->BuildRot;
bMirrored = Params->bMirrored;
}
// LOG_INFO(LogDev, "BuildingClass {}", __int64(BuildingClass));
if (!BuildingClass)
return;
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
TArray<ABuildingSMActor*> ExistingBuildings;
char idk;
@@ -202,7 +218,7 @@ void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController*
if (!bCanBuild)
{
// LOG_INFO(LogDev, "cant build");
return;
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
}
for (int i = 0; i < ExistingBuildings.Num(); i++)
@@ -222,11 +238,13 @@ void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController*
auto BuildingActor = GetWorld()->SpawnActor<ABuildingSMActor>(BuildingClass, Transform);
if (!BuildingActor)
return;
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
BuildingActor->SetPlayerPlaced(true);
BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex());
BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true);
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
}
void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count)
@@ -246,7 +264,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
auto ItemDefinition = Cast<UFortWorldItemDefinition>(ReplicatedEntry->GetItemDefinition());
if (!ItemDefinition)
if (!ItemDefinition || !ItemDefinition->CanBeDropped())
return;
auto Pickup = AFortPickup::SpawnPickup(ItemDefinition, Pawn->GetActorLocation(), Count,
@@ -274,6 +292,14 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
UObject* AbilityToUse = nullptr;
static auto AthenaSprayItemDefinitionClass = FindObject<UClass>("/Script/FortniteGame.AthenaSprayItemDefinition");
if (EmoteAsset->IsA(AthenaSprayItemDefinitionClass))
{
static auto SprayGameplayAbilityDefault = FindObject("/Game/Abilities/Sprays/GAB_Spray_Generic.Default__GAB_Spray_Generic_C");
AbilityToUse = SprayGameplayAbilityDefault;
}
if (!AbilityToUse)
{
static auto EmoteGameplayAbilityDefault = FindObject("/Game/Abilities/Emotes/GAB_Emote_Generic.Default__GAB_Emote_Generic_C");
@@ -296,23 +322,109 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec));
}
void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerController, __int64 DeathReport)
uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = false)
{
static auto ToDeathCauseFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.ToDeathCause");
if (ToDeathCauseFn)
{
struct
{
FGameplayTagContainer InTags; // (ConstParm, Parm, OutParm, ReferenceParm, NativeAccessSpecifierPublic)
bool bWasDBNO; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
uint8_t ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AFortPlayerStateAthena_ToDeathCause_Params{ TagContainer, bWasDBNO };
AFortPlayerStateAthena::StaticClass()->ProcessEvent(ToDeathCauseFn, &AFortPlayerStateAthena_ToDeathCause_Params);
return AFortPlayerStateAthena_ToDeathCause_Params.ReturnValue;
}
static bool bHaveFoundAddress = false;
static uint64 Addr = 0;
if (!bHaveFoundAddress)
{
bHaveFoundAddress = true;
if (Engine_Version == 420)
Addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 0F B6 FA 48 8B D9 E8 ? ? ? ? 33 F6 48 89 74 24").Get();
if (!Addr)
{
LOG_WARN(LogPlayer, "Failed to find ToDeathCause address!");
return 0;
}
}
if (!Addr)
{
return 0;
}
static uint8 (*sub_7FF7AB499410)(FGameplayTagContainer TagContainer, char bWasDBNOIg) = decltype(sub_7FF7AB499410)(Addr);
return sub_7FF7AB499410(TagContainer, bWasDBNO);
}
void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerController, void* DeathReport)
{
auto DeadPawn = Cast<AFortPlayerPawn>(PlayerController->GetPawn());
auto DeadPlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
auto KillerPawn = Cast<AFortPlayerPawn>(*(AFortPawn**)(__int64(DeathReport) + MemberOffsets::DeathReport::KillerPawn));
if (!DeadPawn)
return;
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
static auto DeathInfoStruct = FindObject<UStruct>("/Script/FortniteGame.DeathInfo");
static auto DeathInfoStructSize = DeathInfoStruct->GetPropertiesSize();
auto DeathInfo = Alloc<void>(DeathInfoStructSize);
auto DeathLocation = DeadPawn->GetActorLocation();
static auto FallDamageEnumValue = 1;
auto DeathInfo = (void*)(__int64(DeadPlayerState) + MemberOffsets::FortPlayerStateAthena::DeathInfo); // Alloc<void>(DeathInfoStructSize);
RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize);
auto Tags = *(FGameplayTagContainer*)(__int64(DeathReport) + MemberOffsets::DeathReport::Tags);
// LOG_INFO(LogDev, "Tags: {}", Tags.ToStringSimple(true));
auto DeathCause = ToDeathCause(Tags, false);
LOG_INFO(LogDev, "DeathCause: {}", (int)DeathCause);
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO();
*(uint8*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathCause) = DeathCause;
*(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation;
if (MemberOffsets::DeathInfo::DeathTags != 0)
*(FGameplayTagContainer*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathTags) = Tags;
if (MemberOffsets::DeathInfo::bInitialized != 0)
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bInitialized) = true;
if (DeathCause == FallDamageEnumValue)
{
static auto LastFallDistanceOffset = DeadPawn->GetOffset("LastFallDistance");
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = DeadPawn->Get<float>(LastFallDistanceOffset);
}
else
{
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = KillerPawn ? KillerPawn->GetDistanceTo(DeadPawn) : 0;
}
static auto PawnDeathLocationOffset = DeadPlayerState->GetOffset("PawnDeathLocation");
DeadPlayerState->Get<FVector>(PawnDeathLocationOffset) = DeathLocation;
static auto OnRep_DeathInfoFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.OnRep_DeathInfo");
DeadPlayerState->ProcessEvent(OnRep_DeathInfoFn);
auto DeathLocation = DeadPawn->GetActorLocation();
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
for (int i = 0; i < ItemInstances.Num(); i++)
@@ -334,6 +446,8 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
ItemEntry->GetLoadedAmmo());
}
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
}
void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit)

View File

@@ -28,6 +28,8 @@ struct FFortAthenaLoadout
class AFortPlayerController : public APlayerController
{
public:
static inline void (*ClientOnPawnDiedOriginal)(AFortPlayerController* PlayerController, void* DeathReport);
static inline void (*ServerCreateBuildingActorOriginal)(UObject* Context, FFrame* Stack, void* Ret);
static inline void (*ServerAttemptInteractOriginal)(UObject* Context, FFrame* Stack, void* Ret);
void ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot);
@@ -60,11 +62,12 @@ public:
static void ServerAttemptInteractHook(UObject* Context, FFrame* Stack, void* Ret);
static void ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation);
static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
// static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
static void ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret);
static void ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count);
static void ServerPlayEmoteItemHook(AFortPlayerController* PlayerController, UObject* EmoteAsset);
static void ClientOnPawnDiedHook(AFortPlayerController* PlayerController, __int64 DeathReport);
static void ClientOnPawnDiedHook(AFortPlayerController* PlayerController, void* DeathReport);
static void ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit);
static void ServerEditBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit, UClass* NewBuildingClass, int RotationIterations, char bMirrored);

View File

@@ -38,9 +38,12 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline
{
bFoundFunc = true;
static auto Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! Role(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d").Get();
static auto Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! Role(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d", false).Get();
std::cout << "Addrr: " << Addrr << '\n';
if (!Addrr)
Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! GetLocalRole()(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d").Get();
// std::cout << "Addrr: " << Addrr << '\n';
if (Addrr)
{
@@ -51,11 +54,18 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline
if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53)
{
OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i);
break;
}
if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C)
{
OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i);
break;
}
}
}
// LOG_INFO(LogDev, "OnRep_ZiplineState: 0x{:x}\n", (uintptr_t)OnRep_ZiplineState - __int64(GetModuleHandleW(0)));
LOG_INFO(LogDev, "OnRep_ZiplineState: 0x{:x}\n", (uintptr_t)OnRep_ZiplineState - __int64(GetModuleHandleW(0)));
}
if (OnRep_ZiplineState)

View File

@@ -48,6 +48,7 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
WorldInventory->AddItem(BuildingItemData_RoofS, nullptr);
WorldInventory->AddItem(PickaxeDefinition, nullptr);
WorldInventory->AddItem(WoodItemData, nullptr, 100);
// WorldInventory->AddItem(FindObject<UFortItemDefinition>(L"/ParallelGameplay/Items/WestSausage/WID_WestSausage_Parallel.WID_WestSausage_Parallel"), nullptr, 1, 1000);
WorldInventory->Update(true);
}

View File

@@ -4,9 +4,14 @@
class FScriptInterface
{
private:
public:
UObject* ObjectPointer;
void* InterfacePointer;
FORCEINLINE UObject*& GetObjectRef()
{
return ObjectPointer;
}
};
template<class InterfaceType>

View File

@@ -6,13 +6,13 @@
struct FFrame : public FOutputDevice // https://github.com/EpicGames/UnrealEngine/blob/7acbae1c8d1736bb5a0da4f6ed21ccb237bc8851/Engine/Source/Runtime/CoreUObject/Public/UObject/Stack.h#L83
{
public:
void** VFT;
void** VFT; // 10
// Variables.
UFunction* Node;
UObject* Object;
uint8* Code;
uint8* Locals;
UFunction* Node; // 16
UObject* Object; // 24 // 0x18
uint8* Code; // 32 // 0x20
uint8* Locals; // 40
// MORE STUFF HERE
};

View File

@@ -195,6 +195,7 @@ void Addresses::FindAll()
Addresses::LoadPlayset = FindLoadPlayset();
Addresses::SetZoneToIndex = FindSetZoneToIndex();
Addresses::CompletePickupAnimation = FindCompletePickupAnimation();
Addresses::CanActivateAbility = FindCanActivateAbility();
}
void Addresses::Print()
@@ -233,6 +234,7 @@ void Addresses::Print()
LOG_INFO(LogDev, "LoadPlayset: 0x{:x}", LoadPlayset - Base);
LOG_INFO(LogDev, "SetZoneToIndex: 0x{:x}", SetZoneToIndex - Base);
LOG_INFO(LogDev, "CompletePickupAnimation: 0x{:x}", CompletePickupAnimation - Base);
LOG_INFO(LogDev, "CanActivateAbility: 0x{:x}", CanActivateAbility - Base);
}
void Offsets::FindAll()
@@ -348,6 +350,11 @@ std::vector<uint64> Addresses::GetFunctionsToNull()
// toNull.push_back(Memcury::Scanner::FindPattern("48 89 4C 24 ? 55 56 57 41 56 48 81 EC ? ? ? ? 4C 8B B1 ? ? ? ? 33 F6 4C 89 B4 24 ? ? ? ? 48 8B").Get()); // fritter crash
}
if (Fortnite_Version == 14.60)
{
toNull.push_back(Memcury::Scanner::FindPattern("40 55 57 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 0F B6 FA 44 8B F9 74 3B 80 3D ? ? ? ? ? 0F").Get());
}
if (Fortnite_Version == 17.30)
{
toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 70 08 48 89 78 10 55 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 ED").Get());

View File

@@ -42,6 +42,7 @@ namespace Addresses
extern inline uint64 LoadPlayset = 0;
extern inline uint64 SetZoneToIndex = 0;
extern inline uint64 CompletePickupAnimation = 0;
extern inline uint64 CanActivateAbility = 0;
void SetupVersion(); // Finds Engine Version
void FindAll();

View File

@@ -13,6 +13,7 @@
#include "Map.h"
#include "events.h"
#include "FortKismetLibrary.h"
enum ENetMode
{
@@ -67,6 +68,7 @@ DWORD WINAPI Main(LPVOID)
static auto FortPlayerControllerAthenaDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortPlayerControllerAthena"); // FindObject<UClass>(L"/Game/Athena/Athena_PlayerController.Default__Athena_PlayerController_C");
static auto FortPlayerPawnAthenaDefault = FindObject<UClass>(L"/Game/Athena/PlayerPawn_Athena.Default__PlayerPawn_Athena_C");
static auto FortAbilitySystemComponentAthenaDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortAbilitySystemComponentAthena");
static auto FortKismetLibraryDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortKismetLibrary");
static auto SwitchLevel = FindObject<UFunction>(L"/Script/Engine.PlayerController.SwitchLevel");
FString Level = Engine_Version < 424
@@ -176,7 +178,7 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerPlayEmoteItem"),
AFortPlayerController::ServerPlayEmoteItemHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerCreateBuildingActor"),
AFortPlayerController::ServerCreateBuildingActorHook, nullptr, false);
AFortPlayerController::ServerCreateBuildingActorHook, (PVOID*)&AFortPlayerController::ServerCreateBuildingActorOriginal, false, true);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerBeginEditingBuildingActor"),
AFortPlayerController::ServerBeginEditingBuildingActorHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerEditBuildingActor"),
@@ -189,6 +191,16 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerSendZiplineState"),
AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false);
if (false)
{
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.GiveItemToInventoryOwner"),
UFortKismetLibrary::GiveItemToInventoryOwnerHook, (PVOID*)&UFortKismetLibrary::GiveItemToInventoryOwnerOriginal, false, true);
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer"),
UFortKismetLibrary::K2_RemoveItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveItemFromPlayerOriginal, false, true);
}
static auto ServerHandlePickupInfoFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo");
if (ServerHandlePickupInfoFn)
@@ -202,11 +214,25 @@ DWORD WINAPI Main(LPVOID)
}
if (Globals::bAbilitiesEnabled)
{
static auto PredictionKeyStruct = FindObject<UStruct>("/Script/GameplayAbilities.PredictionKey");
static auto PredictionKeySize = PredictionKeyStruct->GetPropertiesSize();
if (PredictionKeySize == 0x10)
{
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"),
UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false);
UAbilitySystemComponent::ServerTryActivateAbilityHook1, nullptr, false);
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbilityWithEventData"),
UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook, nullptr, false);
UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook1, nullptr, false);
}
else if (PredictionKeySize == 0x18)
{
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"),
UAbilitySystemComponent::ServerTryActivateAbilityHook2, nullptr, false);
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbilityWithEventData"),
UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook2, nullptr, false);
}
// Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"),
// UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false);
}
@@ -223,9 +249,38 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)Addresses::TickFlush, (PVOID)UNetDriver::TickFlushHook, (PVOID*)&UNetDriver::TickFlushOriginal);
// Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal);
// Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr);
Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook, nullptr);
Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook);
Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal);
Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal);
// Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook);
LOG_INFO(LogDev, "Test: 0x{:x}", FindFunctionCall(L"ClientOnPawnDied") - __int64(GetModuleHandleW(0)));
Hooking::MinHook::Hook((PVOID)FindFunctionCall(L"ClientOnPawnDied"), AFortPlayerController::ClientOnPawnDiedHook, (PVOID*)&AFortPlayerController::ClientOnPawnDiedOriginal);
{
MemberOffsets::FortPlayerStateAthena::DeathInfo = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "DeathInfo");
MemberOffsets::DeathInfo::bDBNO = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "bDBNO");
MemberOffsets::DeathInfo::DeathCause = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathCause");
MemberOffsets::DeathInfo::bInitialized = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "bInitialized", false);
MemberOffsets::DeathInfo::Distance = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "Distance");
MemberOffsets::DeathInfo::DeathTags = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathTags", false);
MemberOffsets::DeathInfo::DeathLocation = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathLocation");
MemberOffsets::DeathReport::Tags = FindOffsetStruct("FortniteGame.FortPlayerDeathReport", "Tags");
MemberOffsets::DeathReport::KillerPawn = FindOffsetStruct("FortniteGame.FortPlayerDeathReport", "KillerPawn");
MemberOffsets::DeathReport::KillerPlayerState = FindOffsetStruct("FortniteGame.FortPlayerDeathReport", "KillerPlayerState");
MemberOffsets::DeathReport::DamageCauser = FindOffsetStruct("FortniteGame.FortPlayerDeathReport", "DamageCauser");
}
/* auto GetMaxTickRateIndex = *Memcury::Scanner::FindStringRef(L"GETMAXTICKRATE")
.ScanFor({ 0x4D, 0x8B, 0xC7, 0xE8 })
.RelativeOffset(4)
.ScanFor({ 0xFF, 0x90 })
.AbsoluteOffset(2)
.GetAs<int*>() / 8;
LOG_INFO(LogHook, "GetMaxTickRateIndex {}", GetMaxTickRateIndex); */
srand(time(0));
@@ -258,6 +313,11 @@ DWORD WINAPI Main(LPVOID)
GameMode->Get<float>("WarmupEarlyCountdownDuration") = 0;
}
/* else if (GetAsyncKeyState(VK_F9) & 1)
{
GetWorld()->Listen();
} */
Sleep(1000 / 30);
}

View File

@@ -57,6 +57,62 @@ static inline std::vector<Event> Events =
"/Game/Athena/Playlists/Music/Playlist_Music_High.Playlist_Music_High",
12.41
),
Event(
"Devourer of Worlds",
"/Junior/Blueprints/BP_Junior_Loader.BP_Junior_Loader_C",
"/Junior/Blueprints/BP_Junior_Loader.BP_Junior_Loader_C.LoadJuniorLevel",
1,
{
{
false,
"/Junior/Blueprints/BP_Event_Master_Scripting.BP_Event_Master_Scripting_C.OnReady_872E6C4042121944B78EC9AC2797B053"
}
},
{
{
{
false,
"/Junior/Blueprints/BP_Junior_Scripting.BP_Junior_Scripting_C.startevent"
},
0
}
},
"/Junior/Blueprints/BP_Junior_Scripting.BP_Junior_Scripting_C",
"/Game/Athena/Playlists/Music/Playlist_Junior_32.Playlist_Junior_32",
14.60
),
Event(
"The End",
"",
"",
1,
{
{
false,
"/Game/Athena/Prototype/Blueprints/NightNight/BP_NightNight_Scripting.BP_NightNight_Scripting_C.LoadNightNightLevel" // skunked
},
{
false,
"/Game/Athena/Prototype/Blueprints/NightNight/BP_NightNight_Scripting.BP_NightNight_Scripting_C.OnReady_D0847F7B4E80F01E77156AA4E7131AF6"
}
},
{
{
{
false,
"/Game/Athena/Prototype/Blueprints/NightNight/BP_NightNight_Scripting.BP_NightNight_Scripting_C.startevent"
},
0
}
},
"/Game/Athena/Prototype/Blueprints/NightNight/BP_NightNight_Scripting.BP_NightNight_Scripting_C",
"/Game/Athena/Playlists/Music/Playlist_Music_High.Playlist_Music_High",
10.40
),
Event
(
"Device",
@@ -145,6 +201,33 @@ static inline std::vector<Event> Events =
// "/Buffet/Gameplay/Blueprints/BP_Buffet_Master_Scripting.BP_Buffet_Master_Scripting_C",
"/BuffetPlaylist/Playlist/Playlist_Buffet.Playlist_Buffet",
17.30
),
Event
(
"Ice King Event",
"/Game/Athena/Prototype/Blueprints/Mooney/BP_MooneyLoader.BP_MooneyLoader_C",
"/Game/Athena/Prototype/Blueprints/Mooney/BP_MooneyLoader.BP_MooneyLoader_C.LoadMap",
0,
{
{
false,
"/Game/Athena/Prototype/Blueprints/Mooney/BP_MooneyScripting.BP_MooneyScripting_C.OnReady_9968C1F648044523426FE198948B0CC9"
}
},
{
{
{
false,
"/Game/Athena/Prototype/Blueprints/Mooney/BP_MooneyScripting.BP_MooneyScripting_C.BeginIceKingEvent"
},
0
}
},
"/Game/Athena/Prototype/Blueprints/Mooney/BP_MooneyScripting.BP_MooneyScripting_C",
"/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo",
7.20
)
};
@@ -314,9 +397,11 @@ static inline bool CallOnReadys(bool* bWereAllSuccessful = nullptr)
if (bWereAllSuccessful)
*bWereAllSuccessful = true;
auto EventPlaylist = GetEventPlaylist();
struct { UObject* GameState; UObject* Playlist; FGameplayTagContainer PlaylistContextTags; } OnReadyParams{
((AFortGameModeAthena*)GetWorld()->GetGameMode())->GetGameStateAthena(), GetEventPlaylist(),
GetEventPlaylist()->Get<FGameplayTagContainer>("GameplayTagContainer")};
((AFortGameModeAthena*)GetWorld()->GetGameMode())->GetGameStateAthena(), EventPlaylist,
EventPlaylist ? EventPlaylist->Get<FGameplayTagContainer>("GameplayTagContainer") : FGameplayTagContainer()};
for (auto& OnReadyFunc : OurEvent.OnReadyFunctions)
{
@@ -404,12 +489,13 @@ static inline void StartEvent()
auto EventScripting = GetEventScripting();
LOG_INFO(LogDev, "EventScripting {}", __int64(EventScripting));
if (EventScripting)
LOG_INFO(LogDev, "EventScripting Name {}", EventScripting->GetFullName());
// if (!EventScripting)
// return; // GetEventScripting handles the printing
CallOnReadys();
if (Fortnite_Version == 17.30)

View File

@@ -48,6 +48,19 @@ static inline uintptr_t FindBytes(Memcury::Scanner& Scanner, const std::vector<u
return -1;// Scanner.Get();
}
/* static inline uintptr_t FindBytesArray(Memcury::Scanner& Scanner, const std::vector<std::vector<uint8_t>>& Bytes, int Count = 255, int SkipBytes = 0, bool bGoUp = false, int Skip = 0, const bool bPrint = false)
{
for (auto& ByteArray : Bytes)
{
auto Res = FindBytes(Scanner, ByteArray, Count, SkipBytes, false, Skip, bPrint);
if (Res)
return Res;
}
return 0;
} */
static inline uint64 FindStaticFindObject()
{
if (Engine_Version == 500)
@@ -151,6 +164,9 @@ static inline uint64 FindPauseBeaconRequests()
if (Engine_Version == 426)
return Memcury::Scanner::FindPattern("40 57 48 83 EC 30 48 8B F9 84 D2 74 62 80 3D").Get();
if (Engine_Version == 420)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 30 48 8B D9 84 D2 74 68 80 3D ? ? ? ? ? 72 2C 48 8B 05 ? ? ? ? 4C 8D 44").Get();
auto Addr = Memcury::Scanner::FindStringRef(L"All Beacon Requests Resumed.");
return FindBytes(Addr, { 0x40, 0x53 }, 1000, 0, true);
}
@@ -226,11 +242,38 @@ static inline uint64 FindStaticLoadObject()
static inline uint64 FindCompletePickupAnimation()
{
if (Engine_Version == 420)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B D9 48 8B 89 ? ? ? ? 48 85 C9 74 20 48 8D 44 24").Get();
if (Engine_Version == 421)
return Memcury::Scanner::FindPattern("40 53 56 57 48 83 EC 30 4C 89 6C 24 ? 48 8B F1 4C 8B A9 ? ? ? ? 4D 85 ED 0F 84").Get(); // 6.21
if (Engine_Version == 422)
return Memcury::Scanner::FindPattern("40 53 56 57 48 83 EC 30 4C 89 6C 24 ? 48 8B F1 4C 8B A9 ? ? ? ? 4D 85 ED 0F 84").Get(); // 7.30
if (Engine_Version == 423)
return Memcury::Scanner::FindPattern("40 53 56 48 83 EC 38 4C 89 6C 24 ? 48 8B F1 4C 8B A9 ? ? ? ? 4D 85 ED 0F 84 ? ? ? ? 49 63 8D").Get(); // 10.40
if (Engine_Version == 424)
return Memcury::Scanner::FindPattern("40 53 56 48 83 EC 38 4C 89 6C 24 ? 48 8B F1 4C 8B A9 ? ? ? ? 4D 85 ED 0F 84 ? ? ? ? 49 63 8D").Get(); // 11.31
if (Engine_Version == 425)
return Memcury::Scanner::FindPattern("40 53 56 48 83 EC 38 4C 89 6C 24 ? 48 8B F1 4C 8B A9 ? ? ? ? 4D 85 ED 0F 84 ? ? ? ? 49 63 8D").Get(); // 12.41
if (Engine_Version == 426)
return Memcury::Scanner::FindPattern("40 53 56 48 83 EC 38 4C 89 6C 24 ? 48 8B F1 4C 8B A9 ? ? ? ? 4D 85 ED").Get(); // 14.60
return 0;
}
static inline uint64 FindNoMCP()
{
if (std::floor(Fortnite_Version) == 3)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 48 8D 4C 24 ?").Get();
if (std::floor(Fortnite_Version) == 4)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 83 E0 01").RelativeOffset(1).Get();
auto fn = FindObject<UFunction>("/Script/FortniteGame.FortKismetLibrary.IsRunningNoMCP");
LOG_INFO(LogDev, "fn: {}", __int64(fn));
@@ -240,9 +283,6 @@ static inline uint64 FindNoMCP()
auto noMcpIthink = GetFunctionIdxOrPtr(fn);
return noMcpIthink;
if (Fortnite_Version == 4)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 83 E0 01").RelativeOffset(1).Get();
if (Fortnite_Version >= 17)
{
// todo make this relative
@@ -297,12 +337,8 @@ static inline uint64 FindActorGetNetMode()
if (Engine_Version == 427)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B D9 E8 ? ? ? ? 48 8B 93 ? ? ? ? 48 8B C8 48 8B F8 E8 ? ? ? ? 48 85 C0 75 29").Get();
auto AActorGetNetmode = Memcury::Scanner::FindStringRef(L"ClientPlayerLeft %s")
.ScanFor({ 0x48, 0x8B, 0xCF, 0xE8 })
.RelativeOffset(4)
.Get();
return AActorGetNetmode;
auto AActorGetNetmode = Memcury::Scanner::FindStringRef(L"STAT_ServerUpdateCamera");
return Memcury::Scanner(FindBytes(AActorGetNetmode, { 0xE8 }, 255, 0, true)).RelativeOffset(1).Get();
}
static inline uint64 FindTickFlush()
@@ -319,7 +355,7 @@ static inline uint64 FindTickFlush()
static inline uint64 FindAddNavigationSystemToWorld()
{
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 ED 41").Get();
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 ED 41", false).Get();
}
static inline uint64 FindNavSystemCleanUp()
@@ -350,6 +386,9 @@ static inline uint64 FindGIsServer()
// if (Fortnite_Version == 19.10)
// return __int64(GetModuleHandleW(0)) + 0xB30CF9D;
if (Fortnite_Version == 14.60)
return __int64(GetModuleHandleW(0)) + 0x939930E;
if (Fortnite_Version == 17.30)
return __int64(GetModuleHandleW(0)) + 0x973E499;
@@ -443,6 +482,9 @@ static inline uint64 FindDispatchRequest()
static inline uint64 FindGIsClient()
{
if (Fortnite_Version == 14.60)
return __int64(GetModuleHandleW(0)) + 0x939930D;
if (Fortnite_Version == 17.30)
return __int64(GetModuleHandleW(0)) + 0x973E49B;
@@ -573,6 +615,15 @@ static inline uint64 FindInternalTryActivateAbility()
return FindBytes(Addr, { 0x4C, 0x89, 0x4C }, 1000, 0, true);
}
static inline uint64 FindCanActivateAbility()
{
if (Engine_Version == 421 || Engine_Version == 422)
return Memcury::Scanner::FindPattern("4C 89 4C 24 20 55 56 57 41 56 48 8D 6C 24 D1").Get();
auto Addr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused");
return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true);
}
static inline uint64 FindGiveAbilityAndActivateOnce()
{
if (Engine_Version == 426)
@@ -586,6 +637,12 @@ static inline uint64 FindGiveAbilityAndActivateOnce()
static inline uint64 FindGiveAbility()
{
if (Engine_Version == 420)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 56 57 41 56 48 83 EC 20 83 B9 ? ? ? ? ? 49 8B F0 4C 8B F2 48 8B D9 7E 61").Get();
if (Engine_Version == 421)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 7C 24 ? 41 56 48 83 EC 20 83 B9 ? ? ? ? ? 49 8B E8 4C 8B F2").Get();
// auto Addr = Memcury::Scanner::FindStringRef(L"GiveAbilityAndActivateOnce called on ability %s on the client, not allowed!"); // has 2 refs for some reason on some versions
// auto realGiveAbility = Memcury::Scanner(FindBytes(Addr, { 0xE8 }, 500, 0, false, 0, true)).RelativeOffset(1).Get();
@@ -627,5 +684,5 @@ static inline uint64 FindReplaceBuildingActor()
return 0;
}
return FindBytes(StringRef, { 0x4C, 0x8B }, 1000, 0, true);
return FindBytes(StringRef, (Engine_Version == 420 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x4C, 0x8B }), 1000, 0, true);
}

View File

@@ -3,7 +3,7 @@
namespace Globals
{
extern inline bool bCreative = false;
extern inline bool bGoingToPlayEvent = false;
extern inline bool bGoingToPlayEvent = true;
extern inline bool bNoMCP = true;
extern inline bool bLateGame = false;
extern inline bool bAbilitiesEnabled = true;

View File

@@ -56,6 +56,7 @@ inline void InitLogger()
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>())->set_pattern("[%D-%T] %n: %^%v%$");
sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(logName, true))->set_pattern("[%D-%T] %n: %l: %v");
MakeLogger("LogTeams");
MakeLogger("LogMemory");
MakeLogger("LogFinder");
MakeLogger("LogInit");

View File

@@ -205,13 +205,15 @@ inline void SetBitfield(void* Addr, uint8_t FieldMask, bool NewVal)
*(bool*)Bitfield = NewVal;
}
inline int FindOffsetStruct(const std::string& StructName, const std::string& MemberName)
inline int FindOffsetStruct(const std::string& StructName, const std::string& MemberName, bool bWarnIfNotFound = true)
{
UObject* Struct = FindObject(StructName);
if (!Struct)
{
if (bWarnIfNotFound)
LOG_WARN(LogFinder, "Unable to find struct {}", StructName);
return 0;
}
@@ -257,6 +259,7 @@ inline int FindOffsetStruct(const std::string& StructName, const std::string& Me
}
}
if (bWarnIfNotFound)
LOG_WARN(LogFinder, "Unable to find1 {}", MemberName);
return 0;
@@ -275,8 +278,16 @@ static T* Alloc(size_t Size)
namespace MemberOffsets
{
namespace FortPlayerStateAthena
{
extern inline int DeathInfo = 0;
}
namespace DeathReport
{
extern inline int Tags = 0, KillerPlayerState = 0, KillerPawn = 0, DamageCauser = 0;
}
namespace DeathInfo
{
static inline int bDBNO, Downer, FinisherOrDowner, DeathCause, Distance, DeathLocation, bInitialized, DeathTags;
extern inline int bDBNO = 0, Downer = 0, FinisherOrDowner = 0, DeathCause = 0, Distance = 0, DeathLocation = 0, bInitialized = 0, DeathTags = 0;
}
}

4
vendor/memcury.h vendored
View File

@@ -880,12 +880,12 @@
{
if constexpr (bIsWide)
{
auto aaa = (L"FindStringRef " + std::wstring(string));
auto aaa = (L"failed FindStringRef " + std::wstring(string));
MessageBoxA(0, std::string(aaa.begin(), aaa.end()).c_str(), "Memcury", MB_ICONERROR);
}
else
{
MessageBoxA(0, ("FindStringRef " + std::string(string)).c_str(), "Memcury", MB_ICONERROR);
MessageBoxA(0, ("failed FindStringRef " + std::string(string)).c_str(), "Memcury", MB_ICONERROR);
}
}
}